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 @@
|
|
1
|
+
var sjcl={cipher:{}};sjcl.cipher.aes=function(a){this.a[0][0][0]||this.d();var d,c,g,b,e=this.a[0][4],f=this.a[1];d=a.length;var j=1;this.c=[g=a.slice(0),b=[]];for(a=d;a<4*d+28;a++){c=g[a-1];if(a%d===0||d===8&&a%d===4){c=e[c>>>24]<<24^e[c>>16&255]<<16^e[c>>8&255]<<8^e[c&255];if(a%d===0){c=c<<8^c>>>24^j<<24;j=j<<1^(j>>7)*283}}g[a]=g[a-d]^c}for(d=0;a;d++,a--){c=g[d&3?a:a-4];b[d]=a<=4||d<4?c:f[0][e[c>>>24]]^f[1][e[c>>16&255]]^f[2][e[c>>8&255]]^f[3][e[c&255]]}};sjcl.cipher.aes.prototype={encrypt:function(a){return this.b(a,0)},decrypt:function(a){return this.b(a,1)},a:[[[],[],[],[],[]],[[],[],[],[],[]]],d:function(){var a=this.a[0],d=this.a[1],c=a[4],g=d[4],b,e,f,j=[],l=[],m,i,h,k;for(b=0;b<0x100;b++)l[(j[b]=b<<1^(b>>7)*283)^b]=b;for(e=f=0;!c[e];e^=m||1,f=l[f]||1){h=f^f<<1^f<<2^f<<3^f<<4;h=h>>8^h&255^99;c[e]=h;g[h]=e;i=j[b=j[m=j[e]]];k=i*0x1010101^b*0x10001^m*0x101^e*0x1010100;i=j[h]*0x101^h*0x1010100;for(b=0;b<4;b++){a[b][e]=i=i<<24^i>>>8;d[b][h]=k=k<<24^k>>>8}}for(b=0;b<5;b++){a[b]=a[b].slice(0);d[b]=d[b].slice(0)}},b:function(a,d){var c=this.c[d],g=a[0]^c[0],b=a[d?3:1]^c[1],e=a[2]^c[2];a=a[d?1:3]^c[3];var f,j,l,m=c.length/4-2,i,h=4,k=[0,0,0,0];f=this.a[d];var n=f[0],o=f[1],p=f[2],q=f[3],r=f[4];for(i=0;i<m;i++){f=n[g>>>24]^o[b>>16&255]^p[e>>8&255]^q[a&255]^c[h];j=n[b>>>24]^o[e>>16&255]^p[a>>8&255]^q[g&255]^c[h+1];l=n[e>>>24]^o[a>>16&255]^p[g>>8&255]^q[b&255]^c[h+2];a=n[a>>>24]^o[g>>16&255]^p[b>>8&255]^q[e&255]^c[h+3];h+=4;g=f;b=j;e=l}for(i=0;i<4;i++){k[d?3&-i:i]=r[g>>>24]<<24^r[b>>16&255]<<16^r[e>>8&255]<<8^r[a&255]^c[h++];f=g;g=b;b=e;e=a;a=f}return k}};
|
@@ -0,0 +1,691 @@
|
|
1
|
+
var ul_queue = [];
|
2
|
+
var ul_queue_num = 0;
|
3
|
+
|
4
|
+
var totalbytessent;
|
5
|
+
|
6
|
+
var use_ssl = 1;
|
7
|
+
|
8
|
+
if (localStorage.use_ssl) use_ssl = localStorage.use_ssl;
|
9
|
+
|
10
|
+
var ul_reader;
|
11
|
+
|
12
|
+
var ul_method;
|
13
|
+
|
14
|
+
if (!window.FileReader) ul_method = 1;
|
15
|
+
|
16
|
+
var ul_maxSlots = 4;
|
17
|
+
if (localStorage.ul_maxSlots) ul_maxSlots = localStorage.ul_maxSlots;
|
18
|
+
|
19
|
+
var ul_skipIdentical = 0;
|
20
|
+
if (localStorage.ul_skipIdentical) ul_skipIdentical= localStorage.ul_skipIdentical;
|
21
|
+
|
22
|
+
var ul_maxSpeed = 0;
|
23
|
+
|
24
|
+
if (localStorage.ul_maxSpeed) ul_maxSpeed=localStorage.ul_maxSpeed;
|
25
|
+
|
26
|
+
if (ul_method === 1) ul_maxSpeed=0;
|
27
|
+
|
28
|
+
var ul_xhrs;
|
29
|
+
var ul_xhrbusy;
|
30
|
+
var ul_sendbuf;
|
31
|
+
|
32
|
+
var ul_progress;
|
33
|
+
|
34
|
+
var ul_errors;
|
35
|
+
var ul_intransit;
|
36
|
+
|
37
|
+
var ul_max_workers = 4;
|
38
|
+
var ul_workers;
|
39
|
+
var ul_workerbusy;
|
40
|
+
|
41
|
+
var ul_uploadurl;
|
42
|
+
|
43
|
+
var ul_keyNonce;
|
44
|
+
var ul_key;
|
45
|
+
|
46
|
+
var ul_macs;
|
47
|
+
|
48
|
+
var ul_plainq;
|
49
|
+
|
50
|
+
var ul_sendchunks;
|
51
|
+
var ul_inflight;
|
52
|
+
|
53
|
+
var ul_readq;
|
54
|
+
|
55
|
+
var ul_lastreason = 0;
|
56
|
+
|
57
|
+
var ul_instance = 0;
|
58
|
+
|
59
|
+
var ul_uploading;
|
60
|
+
|
61
|
+
var ul_aes;
|
62
|
+
|
63
|
+
var ul_flashreaderactive = false;
|
64
|
+
|
65
|
+
var ul_flashpos = Array(ul_maxSlots);
|
66
|
+
|
67
|
+
function startupload()
|
68
|
+
{
|
69
|
+
if (ul_uploading) return;
|
70
|
+
|
71
|
+
for (;;)
|
72
|
+
{
|
73
|
+
if (ul_queue_num >= ul_queue.length)
|
74
|
+
{
|
75
|
+
if (d) console.log("No further uploads, clearing ul_queue");
|
76
|
+
ul_queue = [];
|
77
|
+
ul_queue_num = 0;
|
78
|
+
return;
|
79
|
+
}
|
80
|
+
|
81
|
+
if (ul_queue[ul_queue_num])
|
82
|
+
{
|
83
|
+
/*
|
84
|
+
loadImage(ul_queue[ul_queue_num],100,100,function(img)
|
85
|
+
{
|
86
|
+
console.log(img);
|
87
|
+
})
|
88
|
+
*/
|
89
|
+
|
90
|
+
if (!ul_skipIdentical || !file_exists(ul_queue[ul_queue_num].target,ul_queue[ul_queue_num].path || ul_queue[ul_queue_num].name,ul_queue[ul_queue_num].size)) break;
|
91
|
+
onUploadSuccess(ul_queue_num);
|
92
|
+
}
|
93
|
+
|
94
|
+
ul_queue_num++;
|
95
|
+
}
|
96
|
+
|
97
|
+
ul_uploading=true;
|
98
|
+
|
99
|
+
if (ul_queue[ul_queue_num].flashid)
|
100
|
+
{
|
101
|
+
ul_maxSlots = 1;
|
102
|
+
ul_flashreaderactive = false;
|
103
|
+
}
|
104
|
+
else ul_reader = new FileReader();
|
105
|
+
|
106
|
+
if (d) console.log(ul_queue_num + ' - ' + ul_queue.length);
|
107
|
+
|
108
|
+
ul_queue[ul_queue_num].retries = ul_queue[ul_queue_num].retries+1 || 0;
|
109
|
+
|
110
|
+
if (ul_queue[ul_queue_num].posturl) initupload3();
|
111
|
+
else
|
112
|
+
{
|
113
|
+
var ctx = { callback : initupload2, reqindex : [] };
|
114
|
+
var req = [];
|
115
|
+
var maxpf = 128*1048576;
|
116
|
+
|
117
|
+
for (var i = ul_queue_num; i < ul_queue.length && i < ul_queue_num+8 && maxpf > 0; i++)
|
118
|
+
{
|
119
|
+
if (!ul_queue[ul_queue_num].posturl)
|
120
|
+
{
|
121
|
+
ctx.reqindex.push(i);
|
122
|
+
req.push({ a : 'u', ssl : use_ssl, ms : ul_maxSpeed, s : ul_queue[i].size, r : ul_queue[i].retries, e : ul_lastreason });
|
123
|
+
maxpf -= ul_queue[i].size
|
124
|
+
}
|
125
|
+
}
|
126
|
+
|
127
|
+
api_req(req,ctx);
|
128
|
+
}
|
129
|
+
}
|
130
|
+
|
131
|
+
function initupload2(res,ctx)
|
132
|
+
{
|
133
|
+
var p, pp;
|
134
|
+
|
135
|
+
if (typeof res != 'object')
|
136
|
+
{
|
137
|
+
// TODO: process upload error
|
138
|
+
return;
|
139
|
+
}
|
140
|
+
|
141
|
+
for (var i = 0; i < res.length; i++) if (typeof(res[i]) == 'object') ul_queue[ctx.reqindex[i]].posturl = res[i].p;
|
142
|
+
|
143
|
+
initupload3();
|
144
|
+
}
|
145
|
+
|
146
|
+
function initupload3()
|
147
|
+
{
|
148
|
+
ul_uploadurl = ul_queue[ul_queue_num].posturl;
|
149
|
+
|
150
|
+
if (!ul_uploadurl)
|
151
|
+
{
|
152
|
+
// TODO: upload over quota reporting
|
153
|
+
return;
|
154
|
+
}
|
155
|
+
|
156
|
+
ul_key = Array(6);
|
157
|
+
|
158
|
+
// generate ul_key and nonce
|
159
|
+
for (i = 6; i--; ) ul_key[i] = rand(0x100000000);
|
160
|
+
|
161
|
+
ul_keyNonce = JSON.stringify(ul_key);
|
162
|
+
|
163
|
+
ul_macs = [];
|
164
|
+
|
165
|
+
totalbytessent = 0;
|
166
|
+
|
167
|
+
ul_readq = {};
|
168
|
+
|
169
|
+
if (ul_queue[ul_queue_num].size)
|
170
|
+
{
|
171
|
+
p = 0;
|
172
|
+
for (i = 1; i <= 8 && p < ul_queue[ul_queue_num].size-i*131072; i++)
|
173
|
+
{
|
174
|
+
ul_readq[p] = i*131072;
|
175
|
+
pp = p;
|
176
|
+
p += ul_readq[p];
|
177
|
+
}
|
178
|
+
|
179
|
+
while (p < ul_queue[ul_queue_num].size)
|
180
|
+
{
|
181
|
+
ul_readq[p] = 1048576;
|
182
|
+
pp = p;
|
183
|
+
p += ul_readq[p];
|
184
|
+
}
|
185
|
+
|
186
|
+
if (!(ul_readq[pp] = ul_queue[ul_queue_num].size-pp) && ul_queue[ul_queue_num].size) delete ul_readq[pp];
|
187
|
+
}
|
188
|
+
else ul_readq[0] = 0;
|
189
|
+
|
190
|
+
ul_plainq = {};
|
191
|
+
|
192
|
+
ul_intransit = 0;
|
193
|
+
ul_inflight = {};
|
194
|
+
ul_sendchunks = {};
|
195
|
+
|
196
|
+
ul_lastreason = 0;
|
197
|
+
ul_errors = 0;
|
198
|
+
|
199
|
+
ul_progress = Array(ul_maxSlots);
|
200
|
+
|
201
|
+
if (use_workers)
|
202
|
+
{
|
203
|
+
ul_workers = Array(ul_max_workers);
|
204
|
+
ul_workerbusy = Array(ul_max_workers);
|
205
|
+
for (var id = ul_max_workers; id--; ) ul_workerbusy[id] = 0;
|
206
|
+
}
|
207
|
+
else ul_aes = new sjcl.cipher.aes([ul_key[0],ul_key[1],ul_key[2],ul_key[3]]);
|
208
|
+
|
209
|
+
ul_xhrs = Array(ul_maxSlots);
|
210
|
+
ul_xhrbusy = Array(ul_maxSlots);
|
211
|
+
|
212
|
+
if (chromehack) ul_sendbuf = Array(ul_maxSlots);
|
213
|
+
|
214
|
+
for (var slot = ul_maxSlots; slot--; )
|
215
|
+
{
|
216
|
+
ul_xhrbusy[slot] = 0;
|
217
|
+
ul_progress[slot] = 0;
|
218
|
+
if (chromehack) ul_sendbuf[slot] = new ArrayBuffer(1048576);
|
219
|
+
}
|
220
|
+
|
221
|
+
onUploadStart(ul_queue_num);
|
222
|
+
ul_dispatch_chain();
|
223
|
+
}
|
224
|
+
|
225
|
+
var ul_timeout;
|
226
|
+
|
227
|
+
function ul_settimeout(t,target)
|
228
|
+
{
|
229
|
+
clearTimeout(ul_timeout);
|
230
|
+
if (t >= 0) ul_timeout = setTimeout(target,t);
|
231
|
+
}
|
232
|
+
|
233
|
+
function ul_dispatch_chain()
|
234
|
+
{
|
235
|
+
ul_dispatch_read();
|
236
|
+
ul_dispatch_encryption();
|
237
|
+
ul_dispatch_send();
|
238
|
+
}
|
239
|
+
|
240
|
+
function ul_dispatch_encryption()
|
241
|
+
{
|
242
|
+
var id;
|
243
|
+
|
244
|
+
if (use_workers)
|
245
|
+
{
|
246
|
+
for (id = ul_max_workers; id--; ) if (!ul_workerbusy[id]) break;
|
247
|
+
|
248
|
+
if (id >= 0)
|
249
|
+
{
|
250
|
+
for (var p in ul_plainq)
|
251
|
+
{
|
252
|
+
ul_workerbusy[id] = 1;
|
253
|
+
|
254
|
+
if (typeof(ul_workers[id]) == 'object')
|
255
|
+
{
|
256
|
+
delete ul_workers[id].onmessage;
|
257
|
+
ul_workers[id].terminate();
|
258
|
+
ul_workers[id] = undefined;
|
259
|
+
}
|
260
|
+
|
261
|
+
ul_workers[id] = new Worker('encrypter.js');
|
262
|
+
ul_workers[id].postMessage = ul_workers[id].webkitPostMessage || ul_workers[id].postMessage;
|
263
|
+
ul_workers[id].id = id;
|
264
|
+
ul_workers[id].instance = ul_instance;
|
265
|
+
|
266
|
+
ul_workers[id].onmessage = function(e)
|
267
|
+
{
|
268
|
+
if (this.instance == ul_instance)
|
269
|
+
{
|
270
|
+
if (typeof(e.data) == 'string')
|
271
|
+
{
|
272
|
+
if (e.data[0] == '[') ul_macs[this.pos] = JSON.parse(e.data);
|
273
|
+
else if (d) console.log("WORKER" + this.id + ": '" + e.data + "'");
|
274
|
+
}
|
275
|
+
else
|
276
|
+
{
|
277
|
+
if (d) console.log("WORKER" + this.id + ": Received " + e.data.byteLength + " encrypted bytes at " + this.pos);
|
278
|
+
|
279
|
+
ul_sendchunks[this.pos] = new Uint8Array(e.data);
|
280
|
+
|
281
|
+
ul_dispatch_chain();
|
282
|
+
|
283
|
+
ul_workerbusy[this.id] = 0;
|
284
|
+
}
|
285
|
+
}
|
286
|
+
};
|
287
|
+
|
288
|
+
ul_workers[id].postMessage(ul_keyNonce);
|
289
|
+
|
290
|
+
if (d) console.log("WORKER: Queueing " + ul_plainq[p].length + " bytes at " + p);
|
291
|
+
|
292
|
+
ul_workers[id].pos = parseInt(p);
|
293
|
+
ul_workers[id].postMessage(parseInt(p)/16);
|
294
|
+
ul_workers[id].postMessage(ul_plainq[p]);
|
295
|
+
|
296
|
+
delete ul_plainq[p];
|
297
|
+
break;
|
298
|
+
}
|
299
|
+
}
|
300
|
+
}
|
301
|
+
else
|
302
|
+
{
|
303
|
+
for (var p in ul_plainq)
|
304
|
+
{
|
305
|
+
ul_macs[p] = encrypt_ab_ctr(ul_aes,ul_plainq[p],[ul_key[4],ul_key[5]],p);
|
306
|
+
|
307
|
+
ul_sendchunks[p] = ul_plainq[p];
|
308
|
+
|
309
|
+
delete ul_plainq[p];
|
310
|
+
}
|
311
|
+
}
|
312
|
+
}
|
313
|
+
|
314
|
+
function ul_dispatch_send(slot)
|
315
|
+
{
|
316
|
+
var slot;
|
317
|
+
|
318
|
+
for (slot = ul_maxSlots; slot--; )
|
319
|
+
{
|
320
|
+
if (!ul_xhrbusy[slot])
|
321
|
+
{
|
322
|
+
// dispatch lowest-pos sendchunk
|
323
|
+
var p = -1, pp;
|
324
|
+
|
325
|
+
for (pp in ul_sendchunks)
|
326
|
+
{
|
327
|
+
if (!ul_inflight[pp])
|
328
|
+
{
|
329
|
+
pp = parseInt(pp);
|
330
|
+
if (p == -1) p = pp;
|
331
|
+
else if (pp < p) p = pp;
|
332
|
+
}
|
333
|
+
}
|
334
|
+
|
335
|
+
if (p == -1) break;
|
336
|
+
|
337
|
+
if (ul_uploadurl == '' && p >= 0) break;
|
338
|
+
|
339
|
+
ul_inflight[p] = 1;
|
340
|
+
ul_xhrbusy[slot] = 1;
|
341
|
+
|
342
|
+
if (!ul_method)
|
343
|
+
{
|
344
|
+
if (typeof ul_xhrs[slot] != 'object') ul_xhrs[slot] = new XMLHttpRequest;
|
345
|
+
ul_xhrs[slot].slot = slot;
|
346
|
+
|
347
|
+
ul_xhrs[slot].onreadystatechange = function()
|
348
|
+
{
|
349
|
+
ul_settimeout(120000,ul_failed);
|
350
|
+
|
351
|
+
if (this.readyState == this.DONE && this.instance == ul_instance)
|
352
|
+
{
|
353
|
+
if (this.status == 200 && typeof this.response == 'string' && this.statusText == 'OK')
|
354
|
+
{
|
355
|
+
ul_chunkcomplete(this.slot,this.pos,this.response);
|
356
|
+
}
|
357
|
+
else
|
358
|
+
{
|
359
|
+
if (d) console.log("HTTP POST failed with " + this.status + ", error count=" + ul_errors);
|
360
|
+
|
361
|
+
ul_inflight[this.pos] = 0;
|
362
|
+
ul_xhrbusy[this.upload.slot] = 0;
|
363
|
+
ul_progress[this.upload.slot] = 0;
|
364
|
+
ul_updateprogress();
|
365
|
+
|
366
|
+
if (++ul_errors > 16) ul_failed();
|
367
|
+
else ul_settimeout(ul_errors*1000,ul_dispatch_chain);
|
368
|
+
}
|
369
|
+
}
|
370
|
+
}
|
371
|
+
|
372
|
+
ul_xhrs[slot].upload.onprogress = function(e)
|
373
|
+
{
|
374
|
+
ul_settimeout(120000,ul_failed);
|
375
|
+
|
376
|
+
if (this.instance == ul_instance)
|
377
|
+
{
|
378
|
+
if (e.lengthComputable && ul_xhrs[this.slot].pos != 1)
|
379
|
+
{
|
380
|
+
ul_progress[this.slot] = e.loaded;
|
381
|
+
ul_updateprogress();
|
382
|
+
}
|
383
|
+
}
|
384
|
+
}
|
385
|
+
|
386
|
+
ul_xhrs[slot].pos = p;
|
387
|
+
ul_xhrs[slot].instance = ul_instance;
|
388
|
+
ul_xhrs[slot].upload.slot = slot;
|
389
|
+
ul_xhrs[slot].upload.instance = ul_instance;
|
390
|
+
ul_xhrs[slot].open('POST', ul_uploadurl + '/' + p);
|
391
|
+
|
392
|
+
if (chromehack)
|
393
|
+
{
|
394
|
+
data8 = new Uint8Array(ul_sendchunks[p].buffer);
|
395
|
+
send8 = new Uint8Array(ul_sendbuf[slot],0,data8.length);
|
396
|
+
|
397
|
+
send8.set(data8);
|
398
|
+
|
399
|
+
ul_xhrs[slot].send(send8);
|
400
|
+
}
|
401
|
+
else
|
402
|
+
{
|
403
|
+
ul_xhrs[slot].send(ul_sendchunks[p].buffer);
|
404
|
+
}
|
405
|
+
}
|
406
|
+
else
|
407
|
+
{
|
408
|
+
ul_flashpos[slot] = p;
|
409
|
+
flash_uploadchunk(slot,base64urlencode(ul_sendchunks[p].buffer),ul_uploadurl + '/' + p);
|
410
|
+
}
|
411
|
+
|
412
|
+
break;
|
413
|
+
}
|
414
|
+
}
|
415
|
+
}
|
416
|
+
|
417
|
+
function ul_failed(next)
|
418
|
+
{
|
419
|
+
onUploadError(ul_queue_num,"Upload failed - " + (next ? "read error" : "retrying"));
|
420
|
+
|
421
|
+
ul_cancel();
|
422
|
+
if (next) ul_queue_num++;
|
423
|
+
ul_settimeout(1000+(next ? 0 : 1000*ul_queue[ul_queue_num].retries),startupload);
|
424
|
+
}
|
425
|
+
|
426
|
+
function ul_updateprogress()
|
427
|
+
{
|
428
|
+
if (ul_queue[ul_queue_num].size)
|
429
|
+
{
|
430
|
+
var tp = totalbytessent;
|
431
|
+
|
432
|
+
for (var slot = ul_maxSlots; slot--; ) tp += ul_progress[slot];
|
433
|
+
|
434
|
+
if (tp > ul_queue[ul_queue_num].size) tp = ul_queue[ul_queue_num].size;
|
435
|
+
|
436
|
+
onUploadProgress(ul_queue_num, tp, ul_queue[ul_queue_num].size);
|
437
|
+
}
|
438
|
+
}
|
439
|
+
|
440
|
+
var ul_completion = [];
|
441
|
+
var ul_completing;
|
442
|
+
|
443
|
+
function ul_completepending(target)
|
444
|
+
{
|
445
|
+
if (ul_completion.length)
|
446
|
+
{
|
447
|
+
var ul = ul_completion.shift();
|
448
|
+
|
449
|
+
var ctx = {
|
450
|
+
target : target,
|
451
|
+
ul_queue_num : ul[5],
|
452
|
+
callback : ul_completepending2
|
453
|
+
};
|
454
|
+
|
455
|
+
api_completeupload(ul[0],ul[1],ul[2],ul[3],ul[4],ctx);
|
456
|
+
}
|
457
|
+
else ul_completing = false;
|
458
|
+
}
|
459
|
+
|
460
|
+
function ul_completepending2(res,ctx)
|
461
|
+
{
|
462
|
+
onUploadSuccess(ctx.ul_queue_num);
|
463
|
+
ul_completepending(ctx.target);
|
464
|
+
}
|
465
|
+
|
466
|
+
function file_exists(node,path,size)
|
467
|
+
{
|
468
|
+
var p = path.split('/');
|
469
|
+
var n;
|
470
|
+
|
471
|
+
return file_exists2(node,p,size);
|
472
|
+
}
|
473
|
+
|
474
|
+
function file_exists2(node,p,size)
|
475
|
+
{
|
476
|
+
if (!p.length) return false;
|
477
|
+
|
478
|
+
var i, c = p.shift();
|
479
|
+
|
480
|
+
if (!c.length) return file_exists2(node,p,size);
|
481
|
+
|
482
|
+
n = fm_matchname(node,c);
|
483
|
+
|
484
|
+
if (!p.length)
|
485
|
+
{
|
486
|
+
for (i = n.length; i--; )
|
487
|
+
{
|
488
|
+
// TODO: check for further attributes, such as timestamp
|
489
|
+
if (n[i].size == size) return true;
|
490
|
+
}
|
491
|
+
}
|
492
|
+
else for (i = n.length; i--; ) if (n[i].size < 0) return file_exists2(n[i].id,p,size);
|
493
|
+
|
494
|
+
return false;
|
495
|
+
}
|
496
|
+
|
497
|
+
function ul_chunkcomplete(slot,pos,response)
|
498
|
+
{
|
499
|
+
ul_progress[slot] = 0;
|
500
|
+
delete ul_inflight[pos];
|
501
|
+
|
502
|
+
if (response.length > 27) response = base64urldecode(response);
|
503
|
+
|
504
|
+
if (!response.length || response.length == 27)
|
505
|
+
{
|
506
|
+
if (pos >= 0) ul_intransit--;
|
507
|
+
|
508
|
+
if (ul_sendchunks[pos])
|
509
|
+
{
|
510
|
+
totalbytessent += ul_method ? ul_sendchunks[pos].buffer.length : ul_sendchunks[pos].length;
|
511
|
+
ul_updateprogress();
|
512
|
+
delete ul_sendchunks[pos];
|
513
|
+
}
|
514
|
+
|
515
|
+
if (response.length)
|
516
|
+
{
|
517
|
+
var t = [];
|
518
|
+
|
519
|
+
for (p in ul_macs) t.push(p);
|
520
|
+
|
521
|
+
t.sort(function(a,b) { return parseInt(a)-parseInt(b) });
|
522
|
+
|
523
|
+
for (var i = 0; i < t.length; i++) t[i] = ul_macs[t[i]];
|
524
|
+
|
525
|
+
var mac = condenseMacs(t,ul_key);
|
526
|
+
|
527
|
+
ul_settimeout(-1);
|
528
|
+
|
529
|
+
var ctx = { ul_queue_num : ul_queue_num,
|
530
|
+
callback : ul_completepending2
|
531
|
+
};
|
532
|
+
|
533
|
+
var filekey = [ul_key[0]^ul_key[4],ul_key[1]^ul_key[5],ul_key[2]^mac[0]^mac[1],ul_key[3]^mac[2]^mac[3],ul_key[4],ul_key[5],mac[0]^mac[1],mac[2]^mac[3]];
|
534
|
+
|
535
|
+
// TODO: add further attributes, such as filemtime...
|
536
|
+
if (u_k_aes && !ul_completing)
|
537
|
+
{
|
538
|
+
ul_completing = true;
|
539
|
+
api_completeupload(response,ul_queue[ul_queue_num].target,ul_queue[ul_queue_num].path,ul_queue[ul_queue_num].name,filekey,ctx);
|
540
|
+
}
|
541
|
+
else ul_completion.push([response,ul_queue[ul_queue_num].target,ul_queue[ul_queue_num].path,ul_queue[ul_queue_num].name,filekey,ul_queue_num]);
|
542
|
+
|
543
|
+
ul_queue_num++;
|
544
|
+
|
545
|
+
ul_uploading = false;
|
546
|
+
return startupload();
|
547
|
+
}
|
548
|
+
else ul_settimeout(ul_method ? 200000 : 60000,ul_failed);
|
549
|
+
}
|
550
|
+
else return ul_failed()
|
551
|
+
|
552
|
+
// TODO: add processing for re-requests
|
553
|
+
|
554
|
+
ul_xhrbusy[slot] = 0;
|
555
|
+
|
556
|
+
ul_dispatch_chain();
|
557
|
+
}
|
558
|
+
|
559
|
+
function ul_flash_uploaddone(slot,response)
|
560
|
+
{
|
561
|
+
ul_chunkcomplete(slot,ul_flashpos[slot],response);
|
562
|
+
}
|
563
|
+
|
564
|
+
var xhr_supports_typed_arrays = false;
|
565
|
+
|
566
|
+
function ul_dispatch_read()
|
567
|
+
{
|
568
|
+
var rpos;
|
569
|
+
var p;
|
570
|
+
|
571
|
+
if (ul_intransit > 8) return;
|
572
|
+
|
573
|
+
if (!ul_method)
|
574
|
+
{
|
575
|
+
if (ul_reader.readyState != ul_reader.LOADING)
|
576
|
+
{
|
577
|
+
for (p in ul_readq)
|
578
|
+
{
|
579
|
+
p = parseInt(p);
|
580
|
+
|
581
|
+
var blob;
|
582
|
+
|
583
|
+
if ((ul = ul_queue[ul_queue_num].slice) || (ul_queue[ul_queue_num].mozSlice))
|
584
|
+
{
|
585
|
+
if (ul_queue[ul_queue_num].mozSlice) blob = ul_queue[ul_queue_num].mozSlice(p,p+ul_readq[p]);
|
586
|
+
else blob = ul_queue[ul_queue_num].slice(p,p+ul_readq[p]);
|
587
|
+
xhr_supports_typed_arrays = true;
|
588
|
+
}
|
589
|
+
else blob = ul_queue[ul_queue_num].webkitSlice(p,p+ul_readq[p]);
|
590
|
+
|
591
|
+
ul_reader.pos = p;
|
592
|
+
ul_reader.readAsArrayBuffer(blob);
|
593
|
+
ul_reader.instance = ul_instance;
|
594
|
+
|
595
|
+
ul_reader.onloadend = function(evt)
|
596
|
+
{
|
597
|
+
if (this.instance == ul_instance)
|
598
|
+
{
|
599
|
+
if (evt.target.readyState == FileReader.DONE)
|
600
|
+
{
|
601
|
+
delete ul_readq[this.pos];
|
602
|
+
|
603
|
+
ul_plainq[this.pos] = new Uint8Array(evt.target.result);
|
604
|
+
|
605
|
+
ul_intransit++;
|
606
|
+
|
607
|
+
ul_dispatch_chain();
|
608
|
+
}
|
609
|
+
}
|
610
|
+
}
|
611
|
+
|
612
|
+
ul_reader.onerror = function(evt)
|
613
|
+
{
|
614
|
+
if (this.instance == ul_instance)
|
615
|
+
{
|
616
|
+
console.log("File Read error");
|
617
|
+
ul_failed(1);
|
618
|
+
}
|
619
|
+
}
|
620
|
+
|
621
|
+
break;
|
622
|
+
}
|
623
|
+
}
|
624
|
+
}
|
625
|
+
else
|
626
|
+
{
|
627
|
+
if (!ul_flashreaderactive)
|
628
|
+
{
|
629
|
+
ul_flashreaderactive = true;
|
630
|
+
|
631
|
+
for (p in ul_readq)
|
632
|
+
{
|
633
|
+
p = parseInt(p);
|
634
|
+
|
635
|
+
flash_requestchunk(ul_queue[ul_queue_num].flashid,ul_readq[p],p);
|
636
|
+
break;
|
637
|
+
}
|
638
|
+
}
|
639
|
+
}
|
640
|
+
}
|
641
|
+
|
642
|
+
function ul_flash_chunk(id,data,p)
|
643
|
+
{
|
644
|
+
if (ul_flashreaderactive)
|
645
|
+
{
|
646
|
+
ul_flashreaderactive = false;
|
647
|
+
|
648
|
+
if (id != ul_queue[ul_queue_num].flashid)
|
649
|
+
{
|
650
|
+
if (d) console.log("INVALID ID on Flash response");
|
651
|
+
}
|
652
|
+
else
|
653
|
+
{
|
654
|
+
ul_plainq[p] = { buffer : base64urldecode(data) };
|
655
|
+
|
656
|
+
if (ul_plainq[p].buffer.length != ul_readq[p])
|
657
|
+
{
|
658
|
+
if (d) console.log("SHORT READ in flashreader: " + ul_plainq[p].buffer.length + " != " + ul_readq[p] + " at " + p);
|
659
|
+
delete ul_plainq[p];
|
660
|
+
}
|
661
|
+
else
|
662
|
+
{
|
663
|
+
delete ul_readq[p];
|
664
|
+
ul_intransit++;
|
665
|
+
ul_dispatch_chain();
|
666
|
+
}
|
667
|
+
}
|
668
|
+
}
|
669
|
+
}
|
670
|
+
|
671
|
+
function ul_cancel()
|
672
|
+
{
|
673
|
+
if (ul_xhrs)
|
674
|
+
{
|
675
|
+
for (var i = ul_maxSlots; i--; ) if (typeof ul_xhrs[i] == 'object')
|
676
|
+
{
|
677
|
+
ul_xhrs[i].abort();
|
678
|
+
ul_xhrs[i] = undefined;
|
679
|
+
}
|
680
|
+
}
|
681
|
+
|
682
|
+
// TODO: properly abort active Flash components
|
683
|
+
ul_instance++;
|
684
|
+
ul_settimeout(-1);
|
685
|
+
ul_workers = ul_plainq = ul_reader = ul_xhrs = ul_workers = ul_sendchunks = ul_inflight = ul_readq = undefined;
|
686
|
+
ul_uploading = ul_flashreaderactive = false;
|
687
|
+
|
688
|
+
delete ul_queue[ul_queue_num].posturl;
|
689
|
+
|
690
|
+
api_req([{ a : 'u', t : ul_uploadurl }]);
|
691
|
+
}
|