Mega.co.nz DWCode


SUBMITTED BY: Guest

DATE: Feb. 7, 2014, 1:12 p.m.

FORMAT: JavaScript

SIZE: 37.8 kB

HITS: 664

  1. var dl_fs, dl_fw;
  2. var dl_queue = [];
  3. var dl_queue_num = 0;
  4. var dl_retryinterval = 1000;
  5. var dl_method;
  6. // 0: Filesystem API (Chrome / Firefox Extension polyfill
  7. // 1: Adobe Flash SWF Filewriter (fallback for old browsers)
  8. // 2: BlobBuilder (IE10/IE11)
  9. // 3: Deprecated MEGA Firefox Extension
  10. // 4: Arraybuffer/Blob Memory Based
  11. // 5: MediaSource (experimental streaming solution)
  12. // 6: IndexedDB blob based (Firefox 20+)
  13. var blob_urls = [];
  14. var dl_legacy_ie = (typeof XDomainRequest != 'undefined') && (typeof ArrayBuffer == 'undefined');
  15. var dl_flash_connections = 0;
  16. var dl_flash_progress;
  17. var dl_instance = 0;
  18. var dl_blob;
  19. var dl_blob_array = [];
  20. var dl_key;
  21. var dl_keyNonce;
  22. var dl_macs;
  23. var dl_aes;
  24. var dl_filename;
  25. var dl_filesize;
  26. var dl_geturl;
  27. var dl_bytesreceived = 0;
  28. var dl_chunks = [];
  29. var dl_chunksizes;
  30. var dl_storagetype = 0;
  31. var dl_req_storage = false;
  32. var downloading = false;
  33. var dl_maxSlots = 4;
  34. if (localStorage.dl_maxSlots) dl_maxSlots = localStorage.dl_maxSlots;
  35. var dl_xhrs;
  36. var dl_pos;
  37. var dl_progress;
  38. var dl_lastactive;
  39. var dl_cipherq;
  40. var dl_cipherqlen;
  41. var dl_plainq;
  42. var dl_plainqlen;
  43. var dl_lastquotawarning;
  44. var dl_maxWorkers = 4;
  45. var dl_workers;
  46. var dl_workerbusy;
  47. var dl_quotabytes = 0;
  48. var dl_write_position;
  49. var dl_timeout;
  50. var dl_id;
  51. var dl_chunklen;
  52. var skipcheck = 0;
  53. var indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.OIndexedDB || window.msIndexedDB;
  54. var use_idb = false;
  55. var dl_db;
  56. function dl_dispatch_chain()
  57. {
  58. if (downloading)
  59. {
  60. dl_dispatch_read();
  61. dl_dispatch_decryption();
  62. dl_dispatch_write();
  63. }
  64. }
  65. function dl_dispatch_decryption()
  66. {
  67. var p;
  68. if (use_workers)
  69. {
  70. for (var id = dl_maxWorkers; id--; )
  71. {
  72. if (!dl_workerbusy[id]) break;
  73. }
  74. if (id >= 0)
  75. {
  76. for (p in dl_cipherq)
  77. {
  78. dl_workerbusy[id] = 1;
  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. dl_workers[id] = new Worker('decrypter.js');
  86. dl_workers[id].postMessage = dl_workers[id].webkitPostMessage || dl_workers[id].postMessage;
  87. dl_workers[id].id = id;
  88. dl_workers[id].instance = dl_instance;
  89. dl_workers[id].onmessage = function(e)
  90. {
  91. if (this.instance == dl_instance)
  92. {
  93. if (typeof(e.data) == "string")
  94. {
  95. if (e.data[0] == '[') dl_macs[this.dl_pos] = JSON.parse(e.data);
  96. else if (d) console.log("WORKER" + this.id + ": '" + e.data + "'");
  97. }
  98. else
  99. {
  100. var databuf = new Uint8Array(e.data);
  101. if (d) console.log("WORKER" + this.id + ": Received " + databuf.length + " decrypted bytes at " + this.dl_pos);
  102. if (dl_zip && !this.dl_pos)
  103. {
  104. var prefix = ZIPheader(dl_queue[dl_queue_num].p+dl_queue[dl_queue_num].n,dl_queue[dl_queue_num].size,dl_queue[dl_queue_num].t).fileHeader;
  105. var prefixlen = prefix.length;
  106. if (dl_zip.suffix)
  107. {
  108. dl_zip.pos += dl_zip.suffix.length;
  109. t = new Uint8Array(dl_zip.suffix.length+prefix.length);
  110. t.set(dl_zip.suffix);
  111. t.set(prefix,dl_zip.suffix.length);
  112. prefix = t;
  113. }
  114. dl_zip.headerpos = dl_zip.pos;
  115. dl_zip.pos += prefixlen+dl_queue[dl_queue_num].size;
  116. var i, t = new Uint8Array(databuf.length+prefix.length);
  117. t.set(prefix);
  118. t.set(databuf,prefix.length);
  119. dl_chunklen[this.dl_pos] = databuf.length;
  120. databuf = t;
  121. }
  122. dl_plainq[this.dl_pos] = databuf;
  123. dl_plainqlen++;
  124. dl_workerbusy[this.id] = 0;
  125. dl_dispatch_chain();
  126. }
  127. }
  128. };
  129. dl_workers[id].postMessage(dl_keyNonce);
  130. if (d) console.log("WORKER" + id + ": Queueing " + dl_cipherq[p].length + " bytes at " + p);
  131. dl_workers[id].dl_pos = parseInt(p);
  132. dl_workers[id].postMessage(dl_workers[id].dl_pos/16);
  133. dl_workers[id].postMessage(dl_cipherq[p]);
  134. delete dl_cipherq[p];
  135. dl_cipherqlen--;
  136. break;
  137. }
  138. }
  139. else if (d) console.log("All worker threads are busy now.");
  140. }
  141. else
  142. {
  143. for (p in dl_cipherq)
  144. {
  145. if (d) console.log("Decrypting pending block at " + p + " without workers...");
  146. dl_macs[p] = decrypt_ab_ctr(dl_aes,dl_cipherq[p],[dl_key[4],dl_key[5]],p);
  147. dl_plainq[p] = dl_cipherq[p];
  148. delete dl_cipherq[p];
  149. dl_cipherqlen--;
  150. dl_plainqlen++;
  151. break;
  152. }
  153. }
  154. }
  155. function dl_resume(id)
  156. {
  157. if (downloading) dl_dispatch_chain();
  158. else
  159. {
  160. if (id) for (var i = dl_queue.length; i--; ) if (id == dl_queue[i].id)
  161. {
  162. dl_queue_num = i;
  163. break;
  164. }
  165. startdownload();
  166. }
  167. }
  168. var tt;
  169. var dl_zip;
  170. var dl_writing;
  171. function dl_dispatch_write()
  172. {
  173. if (dl_filesize == -1) return;
  174. if ((!document.getElementById('dlswf_' + dl_id)) && (dl_method == 1))
  175. {
  176. if (d) console.log("Flash element not yet initialized");
  177. return;
  178. }
  179. if (dl_writing)
  180. {
  181. if (d) console.log("Writer busy");
  182. return;
  183. }
  184. var p = -1;
  185. // enforce linearity if zipping or not using FileWriter
  186. if (dl_plainq[dl_write_position])
  187. {
  188. p = dl_write_position;
  189. }
  190. else if (d) console.log("Plaintext at " + dl_write_position + " still missing");
  191. if (p < 0)
  192. {
  193. dl_checklostchunk();
  194. return;
  195. }
  196. dl_write_block();
  197. }
  198. function dl_write_block()
  199. {
  200. if (d) console.log("Writing " + dl_plainq[dl_write_position].length + " bytes of file data at dl_pos " + dl_write_position);
  201. if (dl_zip)
  202. {
  203. if (dl_zip.crc32pos != dl_write_position)
  204. {
  205. dl_zip.crc32 = crc32(dl_plainq[dl_write_position],dl_zip.crc32,dl_chunklen[dl_write_position] || dl_plainq[dl_write_position].length);
  206. dl_zip.crc32pos = dl_write_position;
  207. }
  208. }
  209. switch (dl_method)
  210. {
  211. case 0: // Filesystem API (Chrome / Firefox Extension polyfill
  212. dl_writing = true;
  213. dl_fw.instance = dl_instance;
  214. dl_fw.targetpos = dl_fw.position+dl_plainq[dl_write_position].length;
  215. dl_fw.write(new Blob([dl_plainq[dl_write_position]]));
  216. break;
  217. case 1: // Adobe Flash SWF Filewriter (fallback for old browsers)
  218. var j, k;
  219. var len;
  220. if (have_ab) len = dl_plainq[dl_write_position].length;
  221. else len = dl_plainq[dl_write_position].buffer.length;
  222. if (have_ab) subdata = ab_to_base64(dl_plainq[dl_write_position]);
  223. else subdata = base64urlencode(dl_plainq[dl_write_position].buffer);
  224. document.getElementById('dlswf_' + dl_id).flashdata(dl_id,subdata);
  225. dl_ack_write();
  226. break;
  227. case 2: // BlobBuilder IE10
  228. if (have_ab) dl_blob.append(dl_plainq[dl_write_position]);
  229. else dl_blob.append(dl_plainq[dl_write_position].buffer);
  230. dl_ack_write();
  231. break;
  232. case 3: // Deprecated Firefox Extension
  233. console.log(dl_write_position);
  234. ffe_writechunk(ab_to_str(dl_plainq[dl_write_position]),dl_write_position);
  235. dl_ack_write();
  236. break;
  237. case 4: // Blob Memory Based Downloading
  238. dl_blob_array.push(new Blob([dl_plainq[dl_write_position]]));
  239. dl_ack_write();
  240. break;
  241. case 5: // MediaSource (experimental)
  242. try
  243. {
  244. sourceBuffer.append(dl_plainq[dl_write_position]);
  245. }
  246. catch(e)
  247. {
  248. console.log(e);
  249. }
  250. dl_ack_write();
  251. break;
  252. case 6: // IndexedDB blob based (Firefox 20+)
  253. dl_writing = true;
  254. DBWriter.write(dl_write_position);
  255. }
  256. }
  257. function dl_killzip(id)
  258. {
  259. for (var i = dl_queue.length; i--; ) if (id == dl_queue[i].zipid)
  260. dl_queue[i] = false;
  261. }
  262. function dl_ack_write()
  263. {
  264. if (dl_write_position < 0)
  265. {
  266. // zip suffix
  267. dl_complete();
  268. dl_killzip(dl_zip.id);
  269. return startdownload();
  270. }
  271. if (dl_queue[dl_queue_num].data) new Uint8Array(dl_queue[dl_queue_num].data,dl_write_position,dl_plainq[dl_write_position].length).set(dl_plainq[dl_write_position]);
  272. var t = dl_chunklen[dl_write_position] || (have_ab ? dl_plainq[dl_write_position].length : dl_plainq[dl_write_position].buffer.length);
  273. delete dl_plainq[dl_write_position];
  274. dl_plainqlen--;
  275. dl_write_position += t;
  276. dl_dispatch_chain();
  277. }
  278. function dl_write_failed(e)
  279. {
  280. console.log("WRITE FAILED: " + e);
  281. if (dl_write_position < 0)
  282. {
  283. // zip trailer - retry
  284. dl_setTimeout(dl_write_block,1000);
  285. }
  286. else dl_dispatch_chain();
  287. }
  288. function dl_settimer(timeout,target)
  289. {
  290. if (d) console.log(timeout < 0 ? "Stopping timer" : "Starting timer " + timeout);
  291. if (dl_timeout) clearTimeout(dl_timeout);
  292. if (timeout >= 0) dl_timeout = setTimeout(target,timeout);
  293. else dl_timeout = undefined;
  294. }
  295. function dl_next()
  296. {
  297. var zipid = dl_zip && dl_zip.id;
  298. var mi = -1;
  299. var t = new Date().getTime();
  300. var filesleft;
  301. var i;
  302. for (i = 0; i < dl_queue.length; i++) if (dl_queue[i] && !dl_queue[i].complete && (!zipid || zipid == dl_queue[i].zipid))
  303. {
  304. if (!dl_queue[i].mru)
  305. {
  306. mi = i;
  307. break;
  308. }
  309. if (dl_queue[i].retryafter && t < dl_queue[i].retryafter) continue;
  310. if (mi < 0 || dl_queue[i].mru < dl_queue[mi].mru) mi = i;
  311. else filesleft = 1;
  312. }
  313. if (mi >= 0)
  314. {
  315. if (!zipid && dl_queue[mi].zipid) dl_zip = { id : dl_queue[mi].zipid, dirData : [], pos : 0, headerpos : 0, suffix : '', name : dl_queue[mi].zipname, crc32pos : -1 };
  316. dl_queue[mi].mru = t;
  317. return mi;
  318. }
  319. if (filesleft) dl_settimer(5000,startdownload);
  320. else
  321. {
  322. if (zipid)
  323. {
  324. var t = [];
  325. var p = dl_zip.pos+dl_zip.suffix.length;
  326. t.push(dl_zip.suffix);
  327. // t.push(ZIPfolders(dl_zip.id,p));
  328. dl_zip.pos += t[0].length; //+t[1].length;
  329. for (i = 0; i < dl_zip.dirData.length; i++) t.push(dl_zip.dirData[i]);
  330. t.push(ZIPsuffix(p));
  331. var l = 0;
  332. for (i = t.length; i--; ) l += t[i].length;
  333. var b = new Uint8Array(l);
  334. l = 0;
  335. for (i = 0; i < t.length; i++)
  336. {
  337. b.set(t[i],l);
  338. l += t[i].length;
  339. }
  340. dl_plainq = { '-1' : b };
  341. dl_write_position = -1;
  342. dl_write_block(-1);
  343. }
  344. else dl_queue = [];
  345. return -1;
  346. }
  347. }
  348. // try to start download at dl_queue_num
  349. // if that download is not available, loop through the whole dl_queue and try to start
  350. // another one
  351. function startdownload()
  352. {
  353. if (downloading)
  354. {
  355. if (d) console.log("startdownload() called with active download");
  356. return;
  357. }
  358. if (dl_req_storage) return;
  359. dl_queue_num = dl_next();
  360. if (dl_queue_num < 0) return;
  361. dl_settimer(-1);
  362. downloading = true;
  363. dl_key = dl_queue[dl_queue_num].key;
  364. if (d) console.log("dl_key " + dl_key);
  365. if (dl_queue[dl_queue_num].ph) dl_id = dl_queue[dl_queue_num].ph;
  366. else dl_id = dl_queue[dl_queue_num].id;
  367. dl_geturl = '';
  368. dl_bytesreceived = 0;
  369. dl_chunksizes = [];
  370. 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]]);
  371. dl_macs = {};
  372. dl_filesize = -1;
  373. dl_cipherq = [];
  374. dl_cipherqlen = 0;
  375. dl_plainq = [];
  376. dl_plainqlen = 0;
  377. dl_lastquotawarning = 0;
  378. dl_chunklen = {};
  379. dl_pos = Array(dl_maxSlots);
  380. dl_progress = Array(dl_maxSlots);
  381. dl_lastactive = Array(dl_maxSlots);
  382. if (!dl_legacy_ie)
  383. {
  384. dl_xhrs = Array(dl_maxSlots);
  385. for (var slot = dl_maxSlots; slot--; )
  386. {
  387. dl_xhrs[slot] = new XMLHttpRequest;
  388. if (dl_xhrs[slot].overrideMimeType) dl_xhrs[slot].overrideMimeType('text/plain; charset=x-user-defined');
  389. dl_xhrs[slot].slot = slot;
  390. dl_pos[slot] = -1;
  391. dl_progress[slot] = 0;
  392. }
  393. }
  394. else
  395. {
  396. dl_flash_connections = 0;
  397. dl_flash_progress = {};
  398. }
  399. if (use_workers)
  400. {
  401. dl_workers = new Array(dl_maxWorkers);
  402. dl_workerbusy = new Array(dl_maxWorkers);
  403. for (var id = dl_maxWorkers; id--; ) dl_workerbusy[id] = 0;
  404. }
  405. 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]]);
  406. dl_write_position = 0;
  407. dl_getsourceurl(startdownload2);
  408. }
  409. function dl_renewsourceurl()
  410. {
  411. dl_getsourceurl(dl_renewsourceurl2);
  412. }
  413. function dl_getsourceurl(callback)
  414. {
  415. req = { a : 'g', g : 1, ssl : use_ssl };
  416. if (dl_queue[dl_queue_num].ph) req.p = dl_queue[dl_queue_num].ph;
  417. else if (dl_queue[dl_queue_num].id) req.n = dl_queue[dl_queue_num].id;
  418. api_req([req],{ callback : callback });
  419. }
  420. function dl_renewsourceurl2(res,ctx)
  421. {
  422. if (typeof res == 'object')
  423. {
  424. if (typeof res[0] == 'number')
  425. {
  426. dl_reportstatus(dl_queue_num,res[0]);
  427. }
  428. else
  429. {
  430. if (res[0].g)
  431. {
  432. dl_geturl = res[0].g;
  433. dl_dispatch_chain()
  434. return;
  435. }
  436. else if (res[0].e) dl_reportstatus(dl_queue_num,res[0].e);
  437. }
  438. dl_queue[dl_queue_num].retryafter = new Date().getTime()+30000;
  439. startdownload();
  440. }
  441. }
  442. function dl_reportstatus(num,code)
  443. {
  444. if (dl_queue[num])
  445. {
  446. dl_queue[num].lasterror = code;
  447. dl_queue[num].onDownloadError(dl_queue[num].id || dl_queue[num].ph,code);
  448. }
  449. }
  450. function startdownload2(res,ctx)
  451. {
  452. if (typeof res == 'object')
  453. {
  454. if (typeof res[0] == 'number')
  455. {
  456. dl_reportstatus(dl_queue_num,res[0]);
  457. }
  458. else
  459. {
  460. if (res[0].d)
  461. {
  462. dl_reportstatus(dl_queue_num,res[0].d ? 2 : 1);
  463. dl_queue[dl_queue_num] = false;
  464. }
  465. else if (res[0].g)
  466. {
  467. var ab = base64_to_ab(res[0].at);
  468. 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]]);
  469. if (typeof o == 'object' && typeof o.n == 'string')
  470. {
  471. if (have_ab && res[0].pfa && res[0].s <= 48*1048576 && is_image(o.n) && (!res[0].fa || res[0].fa.indexOf(':0*') < 0)) dl_queue[dl_queue_num].data = new ArrayBuffer(res[0].s);
  472. return dl_setcredentials(res[0].g,res[0].s,o.n);
  473. }
  474. else dl_reportstatus(dl_queue_num,EKEY);
  475. }
  476. else dl_reportstatus(dl_queue_num,res[0].e);
  477. }
  478. }
  479. else dl_reportstatus(dl_queue_num,EAGAIN);
  480. downloading = false;
  481. dl_queue_num++;
  482. dl_retryinterval *= 1.2;
  483. dl_settimer(dl_retryinterval,startdownload);
  484. }
  485. function dl_setcredentials(g,s,n)
  486. {
  487. var i;
  488. var p;
  489. var pp;
  490. dl_geturl = g;
  491. dl_filesize = s;
  492. dl_filename = n;
  493. dl_chunks = [];
  494. p = pp = 0;
  495. for (i = 1; i <= 8 && p < dl_filesize-i*131072; i++)
  496. {
  497. dl_chunksizes[p] = i*131072;
  498. dl_chunks.push(p);
  499. pp = p;
  500. p += dl_chunksizes[p];
  501. }
  502. while (p < dl_filesize)
  503. {
  504. dl_chunksizes[p] = 1048576;
  505. dl_chunks.push(p);
  506. pp = p;
  507. p += dl_chunksizes[p];
  508. }
  509. if (!(dl_chunksizes[pp] = dl_filesize-pp))
  510. {
  511. delete dl_chunksizes[pp];
  512. delete dl_chunks[dl_chunks.length-1];
  513. }
  514. if (dl_zip)
  515. {
  516. delete dl_zip.crc32;
  517. dl_zip.crc32pos = -1;
  518. }
  519. if (!dl_zip || !dl_zip.open)
  520. {
  521. if (dl_zip) dl_zip.open = true;
  522. switch (dl_method)
  523. {
  524. case 0: // Chrome (aync)
  525. dl_createtmp();
  526. return;
  527. case 2:
  528. dl_blob = new MSBlobBuilder();
  529. break;
  530. case 3:
  531. ffe_createtmp();
  532. break;
  533. case 4:
  534. dl_blob_array = [];
  535. break;
  536. case 6:
  537. DBWriter.init();
  538. }
  539. }
  540. dl_run();
  541. }
  542. function dl_run()
  543. {
  544. if (dl_filesize)
  545. {
  546. for (var i = dl_maxSlots; i--; ) dl_dispatch_read();
  547. dl_queue[dl_queue_num].onDownloadStart(dl_id,dl_filename,dl_filesize);
  548. }
  549. else dl_checklostchunk();
  550. }
  551. function dl_checklostchunk()
  552. {
  553. var i, p;
  554. if (dl_write_position == dl_filesize)
  555. {
  556. if (dl_filesize)
  557. {
  558. var t = [];
  559. for (p in dl_macs) t.push(p);
  560. t.sort(function(a,b) { return parseInt(a)-parseInt(b) });
  561. for (i = 0; i < t.length; i++) t[i] = dl_macs[t[i]];
  562. 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]]);
  563. }
  564. if (skipcheck) console.log('Expected: [' + dl_key[6] + ',' + dl_key[7] + '], got: [' + (mac[0]^mac[1]) + ',' + (mac[2]^mac[3]) + ']');
  565. downloading = false;
  566. if (have_ab && !skipcheck && dl_filesize && (dl_key[6] != (mac[0]^mac[1]) || dl_key[7] != (mac[2]^mac[3])))
  567. {
  568. dl_reportstatus(dl_queue_num,EKEY);
  569. if (dl_zip) dl_killzip(dl_zip.id);
  570. else dl_queue[dl_queue_num] = false;
  571. }
  572. else
  573. {
  574. if (dl_queue[dl_queue_num].data && !skipcheck) createnodethumbnail(dl_queue[dl_queue_num].id,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]]),++ul_faid,dl_queue[dl_queue_num].data);
  575. if (!dl_zip) dl_complete();
  576. else
  577. {
  578. t = ZIPheader(dl_queue[dl_queue_num].p+dl_queue[dl_queue_num].n,dl_queue[dl_queue_num].size,dl_queue[dl_queue_num].t,dl_zip.crc32,false,dl_zip.headerpos);
  579. dl_zip.suffix = t.dataDescriptor;
  580. dl_zip.dirData.push(t.dirRecord);
  581. dl_queue[dl_queue_num].complete = true;
  582. dl_queue[dl_queue_num].crc32 = dl_zip.crc32;
  583. }
  584. // release all downloads waiting for quota
  585. for (i = dl_queue.length; i--; ) if (dl_queue[i] && dl_queue[i].lasterror == EOVERQUOTA)
  586. {
  587. dl_reportstatus(i,0);
  588. delete dl_queue[i].retryafter;
  589. }
  590. dl_retryinterval = 1000;
  591. }
  592. startdownload();
  593. }
  594. }
  595. function dl_complete()
  596. {
  597. var name;
  598. var path;
  599. if (dl_zip)
  600. {
  601. name = dl_zip.name;
  602. path = false;
  603. }
  604. else
  605. {
  606. name = dl_queue[dl_queue_num].n;
  607. path = dl_queue[dl_queue_num].p;
  608. }
  609. switch (dl_method)
  610. {
  611. case 0:
  612. if (dl_queue_num >= 0) dl_queue[dl_queue_num].onBeforeDownloadComplete();
  613. document.getElementById('dllink').download = name;
  614. document.getElementById('dllink').href = document.fileEntry.toURL();
  615. if (!is_chrome_firefox) document.getElementById('dllink').click();
  616. break;
  617. case 1:
  618. document.getElementById('dlswf_' + dl_id).flashdata(dl_id,'',name);
  619. break;
  620. case 2:
  621. navigator.msSaveOrOpenBlob(dl_blob.getBlob(),name);
  622. break;
  623. case 3:
  624. ffe_complete(name,path);
  625. break;
  626. case 4:
  627. document.getElementById('dllink').download = name;
  628. blob_urls.push(myURL.createObjectURL(new Blob(dl_blob_array)));
  629. document.getElementById('dllink').href = blob_urls[blob_urls.length-1];
  630. document.getElementById('dllink').click();
  631. setTimeout(function()
  632. {
  633. myURL.revokeObjectURL(document.getElementById('dllink').href);
  634. },100);
  635. break;
  636. case 6:
  637. DBWriter.servedl(name);
  638. }
  639. if (dl_zip)
  640. {
  641. fm_zipcomplete(dl_zip.id);
  642. dl_killzip(dl_zip.id);
  643. dl_zip = false;
  644. }
  645. else
  646. {
  647. dl_queue[dl_queue_num].onDownloadComplete(dl_id);
  648. dl_queue[dl_queue_num] = false;
  649. }
  650. }
  651. function dl_httperror(code)
  652. {
  653. if (code == 509)
  654. {
  655. var t = new Date().getTime();
  656. if (!dl_lastquotawarning || t-dl_lastquotawarning > 55000)
  657. {
  658. dl_lastquotawarning = t;
  659. dl_reportstatus(dl_queue_num,code == 509 ? EOVERQUOTA : ETOOMANYCONNECTIONS);
  660. dl_settimer(60000,dl_dispatch_chain);
  661. }
  662. return;
  663. }
  664. dl_reportstatus(dl_queue_num,EAGAIN);
  665. dl_retryinterval *= 1.2;
  666. if (!dl_write_position)
  667. {
  668. dl_cancel();
  669. dl_queue_num++;
  670. dl_settimer(dl_retryinterval,startdownload);
  671. }
  672. else
  673. {
  674. if (d) console.log("Network error, retrying in " + Math.floor(dl_retryinterval)/1000 + " seconds...");
  675. dl_settimer(dl_retryinterval,code == 509 ? dl_dispatch_chain : dl_renewsourceurl);
  676. }
  677. }
  678. function flash_dlprogress(p,numbytes)
  679. {
  680. dl_flash_progress[p] = numbytes;
  681. dl_updateprogress();
  682. }
  683. function dl_flashdldata(p,data,httpcode)
  684. {
  685. dl_flash_connections--;
  686. if (data == 'ERROR' || httpcode != 200)
  687. {
  688. dl_chunks.unshift(p);
  689. var t = new Date().getTime();
  690. dl_httperror(httpcode);
  691. return;
  692. }
  693. data = base64urldecode(data);
  694. delete dl_flash_progress[p];
  695. dl_bytesreceived += data.length;
  696. dl_cipherq[p] = { buffer : data };
  697. dl_cipherqlen++;
  698. dl_updateprogress();
  699. dl_dispatch_chain();
  700. }
  701. function dl_dispatch_read()
  702. {
  703. if (uldl_hold || dl_cipherqlen+dl_plainqlen > dl_maxSlots+40) return;
  704. if (!dl_chunks.length) return;
  705. if (dl_legacy_ie)
  706. {
  707. if (dl_flash_connections > 6) return;
  708. dl_flash_connections++;
  709. var p = dl_chunks[0];
  710. dl_chunks.splice(0,1);
  711. flashdlchunk(p,dl_geturl + '/' + p + '-' + (p+dl_chunksizes[p]-1));
  712. return;
  713. }
  714. for (var slot = dl_maxSlots; slot--; )
  715. if (dl_pos[slot] == -1) break;
  716. if (slot < 0) return;
  717. dl_pos[slot] = dl_chunks[0];
  718. dl_chunks.splice(0,1);
  719. dl_xhrs[slot].instance = dl_instance;
  720. if (d) console.log("Requesting chunk " + dl_pos[slot] + "/" + dl_chunksizes[dl_pos[slot]] + " on slot " + slot + ", " + dl_chunks.length + " remaining");
  721. dl_xhrs[slot].onprogress = function(e)
  722. {
  723. if (this.instance == dl_instance)
  724. {
  725. dl_lastactive[this.slot] = new Date().getTime();
  726. if (!dl_lastquotawarning || new Date().getTime()-dl_lastquotawarning > 55000)
  727. {
  728. if (dl_pos[this.slot] >= 0)
  729. {
  730. dl_progress[this.slot] = e.loaded;
  731. dl_updateprogress();
  732. }
  733. }
  734. }
  735. }
  736. dl_xhrs[slot].onreadystatechange = function()
  737. {
  738. if (this.instance == dl_instance)
  739. {
  740. dl_lastactive[this.slot] = new Date().getTime();
  741. if (this.readyState == this.DONE)
  742. {
  743. if (dl_pos[this.slot] >= 0)
  744. {
  745. if (this.response != null)
  746. {
  747. var p = dl_pos[this.slot];
  748. if (have_ab)
  749. {
  750. if (p >= 0)
  751. {
  752. if (navigator.appName != 'Opera') dl_bytesreceived += this.response.byteLength;
  753. dl_cipherq[p] = new Uint8Array(this.response);
  754. }
  755. }
  756. else
  757. {
  758. // non-IE
  759. if (p >= 0)
  760. {
  761. dl_bytesreceived += this.response.length;
  762. dl_cipherq[p] = { buffer : this.response };
  763. }
  764. }
  765. dl_cipherqlen++;
  766. if (navigator.appName != 'Opera') dl_progress[this.slot] = 0;
  767. dl_updateprogress();
  768. dl_pos[this.slot] = -1;
  769. dl_dispatch_chain();
  770. }
  771. else
  772. {
  773. if (dl_pos[this.slot] != -1)
  774. {
  775. dl_chunks.unshift(dl_pos[this.slot]);
  776. dl_pos[this.slot] = -1;
  777. dl_httperror(this.status);
  778. }
  779. }
  780. }
  781. }
  782. }
  783. }
  784. var range = '/' + dl_pos[slot] + '-' + (dl_pos[slot]+dl_chunksizes[dl_pos[slot]]-1);
  785. if (dl_method) dl_xhrs[slot].open('POST', dl_geturl + range, true);
  786. else
  787. {
  788. // plug extreme Chrome memory leak
  789. var t = dl_geturl.lastIndexOf('/dl/');
  790. dl_xhrs[slot].open('POST', dl_geturl.substr(0,t+1));
  791. dl_xhrs[slot].setRequestHeader("MEGA-Chrome-Antileak",dl_geturl.substr(t) + range);
  792. }
  793. dl_xhrs[slot].responseType = have_ab ? 'arraybuffer' : 'text';
  794. dl_xhrs[slot].send();
  795. }
  796. var dl_prevprogress = 0;
  797. var dl_lastprogress = 0;
  798. function dl_updateprogress()
  799. {
  800. var p = dl_bytesreceived;
  801. if (dl_queue[dl_queue_num])
  802. {
  803. if (dl_legacy_ie) for (var pp in dl_flash_progress) p += dl_flash_progress[pp];
  804. else for (var slot = dl_maxSlots; slot--; ) p += dl_progress[slot];
  805. if (dl_lastprogress+250 > new Date().getTime()) return false;
  806. else dl_lastprogress=new Date().getTime();
  807. dl_queue[dl_queue_num].onDownloadProgress(dl_id, p, dl_filesize, dl_xr.update(p-dl_prevprogress));
  808. dl_prevprogress = p;
  809. }
  810. }
  811. function appendBuffer( buffer1, buffer2 )
  812. {
  813. var tmp = new Uint8Array( buffer1.byteLength + buffer2.byteLength );
  814. tmp.set( new Uint8Array( buffer1 ), 0 );
  815. tmp.set( new Uint8Array( buffer2 ), buffer1.byteLength );
  816. return tmp.buffer;
  817. }
  818. function dl_cancel()
  819. {
  820. dl_settimer(-1);
  821. dl_instance++;
  822. dl_xhrs = dl_pos = dl_workers = dl_progress = dl_cipherq = dl_plainq = dl_progress = dl_chunks = dl_chunksizes = undefined;
  823. downloading = false;
  824. dl_writing = false;
  825. dl_zip = false;
  826. }
  827. var fs_instance;
  828. function dl_retryfsop()
  829. {
  830. if (fs_instance == dl_instance) dl_createtmp();
  831. }
  832. function dl_createtmpfile(fs)
  833. {
  834. dl_fs = fs;
  835. dl_fs.root.getDirectory(dirid, {create: true}, function(dirEntry)
  836. {
  837. if (d) console.log('Directory "' + dirid + '" created')
  838. document.dirEntry = dirEntry;
  839. }, getDirectory_errorHandler);
  840. if (d) console.log("Opening file for writing: " + dl_id);
  841. fs.root.getFile(dirid + '/' + dl_id, {create: true}, function(fileEntry)
  842. {
  843. fileEntry.createWriter(function(fileWriter)
  844. {
  845. if (d) console.log('File "' + dirid + '/' + dl_id + '" created');
  846. dl_fw = fileWriter;
  847. dl_fw.truncate(0);
  848. dl_fw.onerror = function(e)
  849. {
  850. if (d) console.log('Write failed: ' + e.toString());
  851. if (this.instance == dl_instance)
  852. {
  853. dl_writing = false;
  854. dl_write_failed(e);
  855. }
  856. }
  857. dl_fw.onwriteend = function()
  858. {
  859. if (this.instance == dl_instance)
  860. {
  861. if (d) console.log("fileWriter: onwriteend, position: " + this.position + ", expected: " + this.targetpos);
  862. dl_writing = false;
  863. if (this.position == this.targetpos) dl_ack_write();
  864. else dl_write_failed('Short write (' + this.position + ' / ' + this.targetpos + ')');
  865. }
  866. }
  867. document.fileEntry = fileEntry;
  868. dl_run();
  869. }, createWriter_errorHandler);
  870. }, getFile_errorHandler);
  871. }
  872. function RequestFileSystem_errorHandler(e)
  873. {
  874. errorHandler(e,'RequestFileSystem');
  875. }
  876. function getDirectory_errorHandler(e)
  877. {
  878. errorHandler(e,'getDirectory');
  879. }
  880. function createWriter_errorHandler(e)
  881. {
  882. errorHandler(e,'createWriter');
  883. }
  884. function getFile_errorHandler(e)
  885. {
  886. errorHandler(e,'getFile');
  887. }
  888. function errorHandler(e,type)
  889. {
  890. switch (e.code) {
  891. case FileError.QUOTA_EXCEEDED_ERR:
  892. alert('Error writing file, is your harddrive almost full? (' + type + ')');
  893. break;
  894. case FileError.NOT_FOUND_ERR:
  895. alert('NOT_FOUND_ERR in ' + type);
  896. break;
  897. case FileError.SECURITY_ERR:
  898. alert('File transfers do not work with Chrome Incognito.<br>' + '(Security Error in ' + type + ')');
  899. break;
  900. case FileError.INVALID_MODIFICATION_ERR:
  901. alert('INVALID_MODIFICATION_ERR in ' + type);
  902. break;
  903. case FileError.INVALID_STATE_ERR:
  904. fs_instance = dl_instance;
  905. console.log('INVALID_STATE_ERROR in ' + type + ', retrying...');
  906. setTimeout(dl_retryfsop,500);
  907. break;
  908. default:
  909. alert('webkitRequestFileSystem failed in ' + type);
  910. }
  911. }
  912. var dirid = "mega";
  913. function dl_createtmp()
  914. {
  915. window.requestFileSystem(dl_storagetype,1024*1024*1024*25,dl_createtmpfile,RequestFileSystem_errorHandler);
  916. }
  917. if (window.webkitRequestFileSystem)
  918. {
  919. window.requestFileSystem = window.webkitRequestFileSystem;
  920. function dl_getspace(storagetype,minsize)
  921. {
  922. if (!storagetype) storagetype = 0;
  923. if (!minsize) minsize = 0;
  924. window.webkitStorageInfo.queryUsageAndQuota(1, function(used, remaining)
  925. {
  926. if (remaining > 0)
  927. {
  928. dl_quotabytes = remaining;
  929. dl_storagetype=1;
  930. if (dl_quotabytes < 1073741824) clearit(1,3600);
  931. else clearit(1);
  932. startdownload();
  933. }
  934. else
  935. {
  936. var requestbytes = 1024*1024*1024*100;
  937. if (storagetype == 0) requestbytes = 1024*1024*1024*25;
  938. if (storagetype == 1) dl_req_storage = true;
  939. window.webkitStorageInfo.requestQuota(storagetype,requestbytes,function(grantedBytes)
  940. {
  941. window.webkitStorageInfo.queryUsageAndQuota(storagetype, function(used, remaining)
  942. {
  943. if (storagetype == 1) dl_req_storage = false;
  944. dl_quotabytes = remaining;
  945. if (dl_quotabytes < 1073741824) clearit(storagetype,3600);
  946. if ((remaining == 0) && (storagetype == 1))
  947. {
  948. if (!dl_req_storage) dl_getspace(1,minsize);
  949. return false;
  950. }
  951. else if ((minsize > dl_quotabytes) && (storagetype == 0))
  952. {
  953. if (!dl_req_storage) dl_getspace(1,minsize)
  954. return false;
  955. }
  956. else if ((minsize > dl_quotabytes) && (storagetype == 1)) clearit(storagetype,3600);
  957. if (remaining > 0) dl_storagetype = storagetype;
  958. startdownload();
  959. },
  960. function(e)
  961. {
  962. console.log('ERROR: Could not query usage and storage quota. (' + dl_storagetype + ') ' + e);
  963. alert('Could not query usage and storage quota. (' + dl_storagetype + ') ' + e);
  964. });
  965. },
  966. function(e)
  967. {
  968. console.log('ERROR: Could not grant storage space (' + dl_storagetype + ') ' + e);
  969. alert('Could not grant storage space (' + dl_storagetype + ') ' + e);
  970. });
  971. }
  972. },
  973. function(e)
  974. {
  975. console.log('ERROR: Could not query usage and storage quota. (' + dl_storagetype + ') ' + e);
  976. alert('Could not query usage and storage quota. (' + dl_storagetype + ') ' + e);
  977. });
  978. }
  979. dl_getspace(0);
  980. dl_method = 0;
  981. }
  982. else if (navigator.msSaveOrOpenBlob)
  983. {
  984. dl_method = 2;
  985. }
  986. else if ("download" in document.createElementNS("http://www.w3.org/1999/xhtml", "a") && use_idb)
  987. {
  988. function pingDBname()
  989. {
  990. var dbnames = localStorage.dbnames;
  991. if (dbnames) dbnames = JSON.parse(dbnames);
  992. else dbnames = {};
  993. dbnames[DBWriter.iddb_name] =
  994. {
  995. t: new Date().getTime()
  996. };
  997. localStorage.dbnames = JSON.stringify(dbnames);
  998. }
  999. function purgeDBcache()
  1000. {
  1001. var dbnames = localStorage.dbnames;
  1002. if (dbnames)
  1003. {
  1004. dbnames = JSON.parse(dbnames);
  1005. for (var name in dbnames)
  1006. {
  1007. if (((dbnames[name].c) && (dbnames[name].t < (new Date().getTime()-86000000)))
  1008. || (dbnames[name].t < (new Date().getTime()-200000000)))
  1009. {
  1010. try
  1011. {
  1012. window.indexedDB.deleteDatabase(name);
  1013. delete dbnames[name];
  1014. }
  1015. catch (e)
  1016. {
  1017. console.log('Failed to purge cache DB ' + name);
  1018. }
  1019. }
  1020. }
  1021. localStorage.dbnames = JSON.stringify(dbnames);
  1022. }
  1023. }
  1024. purgeDBcache();
  1025. var firefox20 = true;
  1026. dl_method = 6;
  1027. var DBWriter =
  1028. {
  1029. names: {},
  1030. writing: false,
  1031. write: function(p)
  1032. {
  1033. if (localStorage.dbquota) DBWriter.dowrite();
  1034. else
  1035. {
  1036. //ffDialog.start();
  1037. DBWriter.tmpdb = new Date().getTime();
  1038. var request = window.indexedDB.open(DBWriter.tmpdb,1);
  1039. request.onerror = function (error)
  1040. {
  1041. //ffDialog.start();
  1042. if (d) console.log('Error obtaining quota, retrying...');
  1043. DBWriter.write();
  1044. };
  1045. request.onsuccess = function (event)
  1046. {
  1047. DBWriter.tmpiddb = request.result;
  1048. request.getquota();
  1049. },
  1050. request.onupgradeneeded = function (event)
  1051. {
  1052. event.target.result.createObjectStore(DBWriter.tmpdb);
  1053. };
  1054. request.getquota = function ()
  1055. {
  1056. var transaction = DBWriter.tmpiddb.transaction(DBWriter.tmpdb,'readwrite');
  1057. transaction.oncomplete = function()
  1058. {
  1059. //ffDialog.close();
  1060. DBWriter.tmpiddb.close();
  1061. window.indexedDB.deleteDatabase(DBWriter.tmpdb);
  1062. localStorage.dbquota = 1;
  1063. DBWriter.dowrite();
  1064. }
  1065. transaction.onerror = function(event)
  1066. {
  1067. //ffDialog.start();
  1068. DBWriter.write();
  1069. }
  1070. transaction.objectStore(DBWriter.tmpdb).put(new Blob([new ArrayBuffer(62914560)]),'quota');
  1071. }
  1072. }
  1073. },
  1074. dowrite: function()
  1075. {
  1076. var request = window.indexedDB.open(DBWriter.iddb_name, 1);
  1077. request.onerror = function (error)
  1078. {
  1079. dl_write_failed(error);
  1080. };
  1081. request.onsuccess = function (event)
  1082. {
  1083. // hide quota warning dialog
  1084. retry = 0;
  1085. DBWriter.iddb = request.result;
  1086. request.dowrite();
  1087. }
  1088. request.onupgradeneeded = function (event)
  1089. {
  1090. event.target.result.createObjectStore(DBWriter.iddb_name);
  1091. }
  1092. request.dowrite = function()
  1093. {
  1094. var transaction = DBWriter.iddb.transaction(DBWriter.iddb_name,'readwrite');
  1095. transaction.oncomplete = function()
  1096. {
  1097. if (transaction.dl_instance == dl_instance)
  1098. {
  1099. dl_writing = false;
  1100. //ffDialog.close();
  1101. DBWriter.iddb_i++;
  1102. retry = 0;
  1103. DBWriter.iddb.close();
  1104. pingDBname();
  1105. if (d) console.log('DBWriter: Chunk complete');
  1106. dl_ack_write();
  1107. }
  1108. }
  1109. transaction.onerror = function(event)
  1110. {
  1111. dl_writing = false;
  1112. // show quota warning dialog
  1113. DBWriter.write();
  1114. }
  1115. transaction.dl_instance = dl_instance;
  1116. transaction.objectStore(DBWriter.iddb_name).put(new Blob([dl_plainq[dl_write_position]]),'chunk'+DBWriter.iddb_i);
  1117. }
  1118. },
  1119. servedl: function(name)
  1120. {
  1121. if (!name) name = 'file.bin';
  1122. var request = window.indexedDB.open(DBWriter.iddb_name, 1);
  1123. request.onsuccess = function(event)
  1124. {
  1125. var iddb = request.result;
  1126. var transaction = iddb.transaction([DBWriter.iddb_name],'readonly');
  1127. transaction.objectStore(DBWriter.iddb_name).mozGetAll().onsuccess = function(event)
  1128. {
  1129. var dlURL = URL.createObjectURL(new Blob(event.target.result));
  1130. var a = document.getElementById('dllink');
  1131. a.download = name;
  1132. a.href = dlURL;
  1133. a.click();
  1134. };
  1135. }
  1136. },
  1137. init: function()
  1138. {
  1139. DBWriter.iddb_i = 1000000;
  1140. DBWriter.iddb_name = new Date().getTime();
  1141. DBWriter.names[DBWriter.iddb_name] = 1;
  1142. pingDBname()
  1143. }
  1144. };
  1145. $(window).unload(function()
  1146. {
  1147. var dbnames = localStorage.dbnames;
  1148. if (dbnames) dbnames = JSON.parse(dbnames);
  1149. else dbnames = {};
  1150. for (var name in DBWriter.names)
  1151. {
  1152. dbnames[DBWriter.iddb_name] =
  1153. {
  1154. t: new Date().getTime(),
  1155. c: 1
  1156. };
  1157. }
  1158. localStorage.dbnames = JSON.stringify(dbnames);
  1159. });
  1160. }
  1161. else if ("download" in document.createElementNS("http://www.w3.org/1999/xhtml", "a"))
  1162. {
  1163. dl_method = 4;
  1164. }
  1165. else
  1166. {
  1167. // Flash fallback
  1168. dl_method = 1;
  1169. }
  1170. if (localStorage.dlmethod) dl_method = parseInt(localStorage.dlmethod);
  1171. function getxr()
  1172. {
  1173. return {
  1174. update : function(b)
  1175. {
  1176. var ts = new Date().getTime();
  1177. if (b < 0)
  1178. {
  1179. this.tb = {};
  1180. this.st = 0;
  1181. return 0;
  1182. }
  1183. if (b) this.tb[ts] = this.tb[ts] ? this.tb[ts]+b : b;
  1184. b = 0;
  1185. for (t in this.tb)
  1186. {
  1187. t = parseInt(t);
  1188. if (t < ts-this.window) delete this.tb[t];
  1189. else b += this.tb[t];
  1190. }
  1191. if (!b)
  1192. {
  1193. this.st = 0;
  1194. return 0;
  1195. }
  1196. else if (!this.st) this.st = ts;
  1197. if (!(ts -= this.st)) return 0;
  1198. if (ts > this.window) ts = this.window;
  1199. return b/ts;
  1200. },
  1201. tb : {},
  1202. st : 0,
  1203. window : 60000
  1204. }
  1205. }
  1206. var dl_xr = getxr();
  1207. var uldl_hold = false;
  1208. function uldl_pause()
  1209. {
  1210. uldl_hold = true;
  1211. }
  1212. function uldl_resume()
  1213. {
  1214. var i;
  1215. uldl_hold = false;
  1216. if (downloading) for (i = dl_maxSlots; i--; ) dl_dispatch_chain();
  1217. if (ul_uploading) for (i = ul_maxSlots; i--; ) ul_dispatch_chain();

comments powered by Disqus