Skip to content

Commit e8a78b5

Browse files
duan007aPeterRao
authored andcommitted
feat: browser support blob (#409)
* feature: add support with blob * fix: fix typo * test: add test cases for blob's upload operation * feat: rm unused test data (#401) * fix: add invalidation for security * test: update test case * feat: add example about upload blob * fix: restore test data * fix: restore test data
1 parent 64f8d68 commit e8a78b5

File tree

5 files changed

+117
-14
lines changed

5 files changed

+117
-14
lines changed

example/index.html

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ <h1>OSS <small>in</small> Browser</h1>
6262
<div class="form-group">
6363
<label>Store as</label>
6464
<input type="text" class="form-control" id="object-key-content" value="object" />
65-
</div>
6665
<div class="form-group">
6766
<input type="button" class="btn btn-primary" id="content-button" value="Save" />
6867
</div>
@@ -72,6 +71,26 @@ <h1>OSS <small>in</small> Browser</h1>
7271
</td>
7372
</tr>
7473
<tr>
74+
<td>
75+
<div class="panel panel-success">
76+
<div class="panel-heading">Upload Blob</div>
77+
<div class="panel-body">
78+
<form action="" class="form-horizontal">
79+
<div class="form-group">
80+
<label>Content</label>
81+
<textarea class="form-control" id="file-blob" rows="3">Hello, OSS! I am a Blob!</textarea>
82+
</div>
83+
<div class="form-group">
84+
<label>Store as</label>
85+
<input type="text" class="form-control" id="object-key-blob" value="blob" />
86+
</div>
87+
<div class="form-group">
88+
<input type="button" class="btn btn-primary" id="blob-button" value="Save" />
89+
</div>
90+
</form>
91+
</div>
92+
</div>
93+
</td>
7594
<td>
7695
<div class="panel panel-danger">
7796
<div class="panel-heading">Upload with base64 img</div>
@@ -104,7 +123,8 @@ <h1>OSS <small>in</small> Browser</h1>
104123
</div>
105124
</div>
106125
</td>
107-
126+
</tr>
127+
<tr>
108128
<td>
109129
<div class="panel panel-warning">
110130
<div class="panel-heading">Download file</div>
@@ -125,8 +145,6 @@ <h1>OSS <small>in</small> Browser</h1>
125145
</div>
126146
</div>
127147
</td>
128-
</tr>
129-
<tr>
130148
<td>
131149
<div class="panel panel-info">
132150
<div class="panel-heading">List files</div>

example/index.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,14 @@ const uploadContent = function (client) {
174174
return client.put(key, new Buffer(content)).then(res => listFiles(client));
175175
};
176176

177+
const uploadBlob = function (client) {
178+
const content = document.getElementById('file-blob').value.trim();
179+
const key = document.getElementById('object-key-blob').value.trim() || 'blob';
180+
console.log(`content => ${key}`);
181+
182+
return client.put(key, new Blob([content], { type: 'text/plain' })).then(res => listFiles(client));
183+
}
184+
177185

178186
const downloadFile = function (client) {
179187
const object = document.getElementById('dl-object-key').value.trim();
@@ -209,6 +217,10 @@ window.onload = function () {
209217
applyTokenDo(uploadContent);
210218
};
211219

220+
document.getElementById('blob-button').onclick = function () {
221+
applyTokenDo(uploadBlob);
222+
};
223+
212224
document.getElementById('list-files-button').onclick = function () {
213225
applyTokenDo(listFiles);
214226
};

lib/browser/managed_upload.js

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,17 @@ proto.multipartUpload = function* multipartUpload(name, file, options) {
3636
}
3737

3838
const minPartSize = 100 * 1024;
39-
const filename = is.file(file) ? file.name : file;
40-
options.mime = options.mime || mime.getType(path.extname(filename));
39+
40+
if (!options.mime) {
41+
if (is.file(file)) {
42+
options.mime = mime.getType(path.extname(file.name));
43+
} else if (is.blob(file)) {
44+
options.mime = file.type;
45+
} else {
46+
options.mime = mime.getType(path.extname(file));
47+
}
48+
}
49+
4150
options.headers = options.headers || {};
4251
this._convertMetaToHeaders(options.meta, options.headers);
4352

@@ -182,13 +191,17 @@ is.file = function file(obj) {
182191
return typeof (File) !== 'undefined' && obj instanceof File;
183192
};
184193

194+
is.blob = function (blob) {
195+
return typeof (Blob) !== 'undefined' && blob instanceof Blob;
196+
};
197+
185198
/**
186199
* Get file size
187200
*/
188201
proto._getFileSize = function* _getFileSize(file) {
189202
if (is.buffer(file)) {
190203
return file.length;
191-
} else if (is.file(file)) {
204+
} else if (is.blob(file) || is.file(file)) {
192205
return file.size;
193206
} if (is.string(file)) {
194207
const stat = yield this._statFile(file);
@@ -261,7 +274,7 @@ WebFileReadStream.prototype._read = function _read(size) {
261274
};
262275

263276
proto._createStream = function _createStream(file, start, end) {
264-
if (is.file(file)) {
277+
if (is.blob(file) || is.file(file)) {
265278
return new WebFileReadStream(file.slice(start, end));
266279
}
267280
// else if (is.string(file)) {

lib/browser/object.js

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,15 +65,20 @@ proto.put = function* put(name, file, options) {
6565
options = options || {};
6666
if (is.buffer(file)) {
6767
content = file;
68-
} else if (is.string(file)) {
69-
options.mime = options.mime || mime.getType(path.extname(file));
70-
const stream = fs.createReadStream(file);
68+
} else if (is.blob(file) || is.file(file)) {
69+
if (!options.mime) {
70+
if (is.file(file)) {
71+
options.mime = mime.getType(path.extname(file.name));
72+
} else {
73+
options.mime = file.type;
74+
}
75+
}
76+
77+
const stream = this._createStream(file, 0, file.size);
7178
options.contentLength = yield this._getFileSize(file);
7279
return yield this.putStream(name, stream, options);
73-
} else if (is.readableStream(file)) {
74-
return yield this.putStream(name, file, options);
7580
} else {
76-
throw new TypeError('Must provide String/Buffer/ReadableStream for put.');
81+
throw new TypeError('Must provide Buffer/Blob for put.');
7782
}
7883

7984
options.headers = options.headers || {};

test/browser/browser.test.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,28 @@ describe('browser', () => {
471471

472472
assert.equal(resultGet.content.toString(), body.toString());
473473

474+
const resultDel = yield this.store.delete(name);
475+
assert.equal(resultDel.res.status, 204);
476+
});
477+
it('GETs and PUTs blob to a bucket', function* () {
478+
const name = `${prefix}put/test`;
479+
const body = new Blob(['blobBody'], { type: 'text/plain' });
480+
const resultPut = yield this.store.put(name, body);
481+
assert.equal(resultPut.res.status, 200);
482+
const resultGet = yield this.store.get(name);
483+
assert.equal(resultGet.res.status, 200);
484+
485+
486+
yield new Promise((resolve) => {
487+
const fr = new FileReader();
488+
fr.onload = function () {
489+
console.log(fr.result);
490+
assert.equal(resultGet.content.toString(), fr.result);
491+
resolve();
492+
};
493+
fr.readAsText(body, 'utf-8');
494+
});
495+
474496
const resultDel = yield this.store.delete(name);
475497
assert.equal(resultDel.res.status, 204);
476498
});
@@ -762,6 +784,39 @@ describe('browser', () => {
762784
assert.deepEqual(md5(object.content), md5(fileBuf));
763785
});
764786

787+
it('should upload file using multipart upload', function* () {
788+
// create a file with 1M random data
789+
const blobContent = Array(1024 * 1024).fill('a').join('');
790+
const blob = new Blob([blobContent], { type: 'text/plain' });
791+
792+
const name = `${prefix}multipart/upload-blob.js`;
793+
let progress = 0;
794+
const result = yield this.store.multipartUpload(name, blob, {
795+
partSize: 100 * 1024,
796+
progress() {
797+
return function (done) {
798+
progress++;
799+
done();
800+
};
801+
},
802+
});
803+
sinon.restore();
804+
assert.equal(result.res.status, 200);
805+
assert.equal(progress, 12);
806+
807+
const object = yield this.store.get(name);
808+
assert.equal(object.res.status, 200);
809+
810+
const blobBuf = new Uint8Array(blobContent.length);
811+
for (let i = 0, j = blobContent.length; i < j; ++i) {
812+
blobBuf[i] = blobContent.charCodeAt(i);
813+
}
814+
815+
assert.equal(object.content.length, blobBuf.length);
816+
// avoid comparing buffers directly for it may hang when generating diffs
817+
assert.deepEqual(md5(object.content), md5(blobBuf));
818+
});
819+
765820
it('should return requestId in init, upload part, complete', function* () {
766821
const fileContent = Array(1024 * 1024).fill('a').join('');
767822
const file = new File([fileContent], 'multipart-fallback');

0 commit comments

Comments
 (0)