@karpeleslab/klbfw 0.1.8 → 0.1.9

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/upload.js +100 -44
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@karpeleslab/klbfw",
3
- "version": "0.1.8",
3
+ "version": "0.1.9",
4
4
  "description": "Frontend Framework",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/upload.js CHANGED
@@ -117,35 +117,55 @@ module.exports.upload = (function () {
117
117
  params["type"] = up.file.type;
118
118
 
119
119
  rest.rest(up.path, "POST", params, up.context).then(function (res) {
120
- if (!res["data"]["Cloud_Aws_Bucket_Upload__"]) {
121
- // invalid data
122
- up.reject();
123
- delete upload_running[up.up_id];
124
- upload_failed.push(up);
125
- return;
120
+ // Method 1: aws signed multipart upload
121
+ if (res["data"]["Cloud_Aws_Bucket_Upload__"]) {
122
+ up.info = res["data"]; // contains stuff like Bucket_Endpoint, Key, etc
123
+
124
+ // ok we are ready to upload - this will initiate an upload
125
+ awsReq(up.info, "POST", "uploads=", "", {"Content-Type": up.file.type, "X-Amz-Acl": "private"}, up.context)
126
+ .then(response => response.text())
127
+ .then(str => (new DOMParser()).parseFromString(str, "text/xml"))
128
+ .then(dom => dom.querySelector('UploadId').innerHTML)
129
+ .then(function (uploadId) {
130
+ up.uploadId = uploadId;
131
+
132
+ // ok, let's compute block size so we know how many parts we need to send
133
+ var fsize = up.file.size;
134
+ var bsize = Math.ceil(fsize / 10000); // we want ~10k parts
135
+ if (bsize < 5242880) bsize = 5242880; // minimum block size = 5MB
136
+
137
+ up.method = 'aws';
138
+ up.bsize = bsize;
139
+ up.blocks = Math.ceil(fsize / bsize);
140
+ up.b = {};
141
+ up['status'] = 'uploading';
142
+ upload.run();
143
+ }).catch(res => failure(up, res))
144
+ return;
126
145
  }
146
+ // Method 2: PUT requests
147
+ if (res["data"]["PUT"]) {
148
+ var fsize = up.file.size;
149
+ var bsize = fsize; // upload file in a single block
150
+ if (res["data"]["Blocksize"]) {
151
+ // this upload target supports multipart PUT upload
152
+ bsize = res["data"]["Blocksize"]; // multipart upload
153
+ }
127
154
 
128
- up.info = res["data"]; // contains stuff like Bucket_Endpoint, Key, etc
129
-
130
- // ok we are ready to upload - this will initiate an upload
131
- awsReq(up.info, "POST", "uploads=", "", {"Content-Type": up.file.type, "X-Amz-Acl": "private"}, up.context)
132
- .then(response => response.text())
133
- .then(str => (new DOMParser()).parseFromString(str, "text/xml"))
134
- .then(dom => dom.querySelector('UploadId').innerHTML)
135
- .then(function (uploadId) {
136
- up.uploadId = uploadId;
137
-
138
- // ok, let's compute block size so we know how many parts we need to send
139
- var fsize = up.file.size;
140
- var bsize = Math.ceil(fsize / 10000); // we want ~10k parts
141
- if (bsize < 5242880) bsize = 5242880; // minimum block size = 5MB
142
-
143
- up.bsize = bsize;
144
- up.blocks = Math.ceil(fsize / bsize);
145
- up.b = {};
146
- up['status'] = 'uploading';
147
- upload.run();
148
- }).catch(res => failure(up, res))
155
+ up.info = res["data"];
156
+ up.method = 'put';
157
+ up.bsize = bsize;
158
+ up.blocks = Math.ceil(fsize / bsize);
159
+ up.b = {};
160
+ up['status'] = 'uploading';
161
+ upload.run();
162
+ return;
163
+ }
164
+ // invalid data
165
+ up.reject();
166
+ delete upload_running[up.up_id];
167
+ upload_failed.push(up);
168
+ return;
149
169
  })
150
170
  .catch(res => failure(up, res));
151
171
  }
@@ -185,12 +205,34 @@ module.exports.upload = (function () {
185
205
 
186
206
  var reader = new FileReader();
187
207
  reader.addEventListener("loadend", function () {
188
- awsReq(up.info, "PUT", "partNumber=" + (partno + 1) + "&uploadId=" + up.uploadId, reader.result, null, up.context)
189
- .then(function (response) {
190
- up.b[partno] = response.headers.get("ETag");
208
+ switch(up.method) {
209
+ case 'aws':
210
+ awsReq(up.info, "PUT", "partNumber=" + (partno + 1) + "&uploadId=" + up.uploadId, reader.result, null, up.context)
211
+ .then(function (response) {
212
+ up.b[partno] = response.headers.get("ETag");
213
+ sendprogress();
214
+ upload.run();
215
+ }).catch(res => failure(up, res));
216
+ case 'put':
217
+ let headers = {};
218
+ headers["Content-Type"] = up.file.type;
219
+ if (up.blocks > 1) {
220
+ // add Content-Range header
221
+ // Content-Range: bytes start-end/*
222
+ const end = start + reader.result.byteLength - 1; // inclusive
223
+ headers["Content-Range"] = "bytes "+start+"-"+end+"/*";
224
+ }
225
+
226
+ fetch(up.info["PUT"], {
227
+ method: "PUT",
228
+ body: reader.result,
229
+ headers: headers,
230
+ }).then(function (response) {
231
+ up.b[partno] = "done";
191
232
  sendprogress();
192
233
  upload.run();
193
234
  }).catch(res => failure(up, res));
235
+ }
194
236
  });
195
237
 
196
238
  reader.addEventListener("error", function (e) {
@@ -221,19 +263,33 @@ module.exports.upload = (function () {
221
263
  up["done"] = d;
222
264
 
223
265
  if (p == 0) {
224
- // complete, see https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadComplete.html
225
- up["status"] = "validating";
226
- var xml = "<CompleteMultipartUpload>";
227
- for (var i = 0; i < up.blocks; i++) {
228
- xml += "<Part><PartNumber>" + (i + 1) + "</PartNumber><ETag>" + up.b[i] + "</ETag></Part>";
229
- }
230
- xml += "</CompleteMultipartUpload>";
231
- awsReq(up.info, "POST", "uploadId=" + up.uploadId, xml, null, up.context)
232
- .then(response => response.text())
233
- .then(function (r) {
234
- // if success, need to call finalize
235
- rest.rest("Cloud/Aws/Bucket/Upload/" + up.info.Cloud_Aws_Bucket_Upload__ + ":handleComplete", "POST", {}, up.context).then(function (ares) {
236
- // SUCCESS!
266
+ switch(up.method) {
267
+ case 'aws':
268
+ // complete, see https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadComplete.html
269
+ up["status"] = "validating";
270
+ var xml = "<CompleteMultipartUpload>";
271
+ for (var i = 0; i < up.blocks; i++) {
272
+ xml += "<Part><PartNumber>" + (i + 1) + "</PartNumber><ETag>" + up.b[i] + "</ETag></Part>";
273
+ }
274
+ xml += "</CompleteMultipartUpload>";
275
+ awsReq(up.info, "POST", "uploadId=" + up.uploadId, xml, null, up.context)
276
+ .then(response => response.text())
277
+ .then(function (r) {
278
+ // if success, need to call finalize
279
+ rest.rest("Cloud/Aws/Bucket/Upload/" + up.info.Cloud_Aws_Bucket_Upload__ + ":handleComplete", "POST", {}, up.context).then(function (ares) {
280
+ // SUCCESS!
281
+ up["status"] = "complete";
282
+ up["final"] = ares["data"];
283
+ sendprogress();
284
+ up.resolve(up);
285
+ delete upload_running[up.up_id];
286
+ upload.run();
287
+ }).catch(res => failure(up, res));
288
+ }).catch(res => failure(up, res));
289
+ case 'put':
290
+ // complete, directly call handleComplete
291
+ rest.rest(up.info.Complete, "POST", {}, up.context).then(function (ares) {
292
+ // success!
237
293
  up["status"] = "complete";
238
294
  up["final"] = ares["data"];
239
295
  sendprogress();
@@ -241,7 +297,7 @@ module.exports.upload = (function () {
241
297
  delete upload_running[up.up_id];
242
298
  upload.run();
243
299
  }).catch(res => failure(up, res));
244
- }).catch(res => failure(up, res));
300
+ }
245
301
  }
246
302
  }
247
303