Skip to content

Commit

Permalink
feat: provide a switch to generate upload file md5 (#945)
Browse files Browse the repository at this point in the history
  • Loading branch information
beajer committed Mar 25, 2021
1 parent 59aca92 commit 2d65189
Show file tree
Hide file tree
Showing 8 changed files with 63 additions and 13 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1610,6 +1610,7 @@ parameters:
- 'Content-Encoding' object content encoding for download, e.g.: `Content-Encoding: gzip`
- 'Expires' expires time for download, an absolute date and time. e.g.: `Tue, 08 Dec 2020 13:49:43 GMT`
- See more: [PutObject](https://help.aliyun.com/document_detail/31978.html#title-yxe-96d-x61)
- [disabledMD5] {Boolean} default true, it just work in Browser. if false,it means that MD5 is automatically calculated for uploaded files. **_NOTE:_** Synchronous computing tasks will block the main process

Success will return the object information.

Expand Down Expand Up @@ -3061,6 +3062,7 @@ parameters:
- 'Expires' expires time for download, an absolute date and time. e.g.: `Tue, 08 Dec 2020 13:49:43 GMT`
- **NOTE**: Some headers are [disabled in browser][disabled-browser-headers]
- [timeout] {Number} Milliseconds before a request is considered to be timed out
- [disabledMD5] {Boolean} default true, it just work in Browser. if false,it means that MD5 is automatically calculated for uploaded files. **_NOTE:_** Synchronous computing tasks will block the main process
Success will return:
Expand Down
3 changes: 1 addition & 2 deletions lib/browser/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ Client.initOptions = function initOptions(options) {
const opts = Object.assign({
secure: isHttpsWebProtocol(),
// for browser compatibility disable fetch.
useFetch: false
useFetch: false,
}, options);

return _initOptions(opts);
Expand Down Expand Up @@ -215,7 +215,6 @@ proto.request = async function (params) {

async function request(params) {
const reqParams = createRequest.call(this, params);

if (!this.options.useFetch) {
reqParams.params.mode = 'disable-fetch';
}
Expand Down
4 changes: 3 additions & 1 deletion lib/browser/managed-upload.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const proto = exports;
*/
proto.multipartUpload = async function multipartUpload(name, file, options = {}) {
this.resetCancelFlag();
options.disabledMD5 = options.disabledMD5 === undefined ? true : !!options.disabledMD5;
if (options.checkpoint && options.checkpoint.uploadId) {
if (file && isFile(file)) options.checkpoint.file = file;

Expand Down Expand Up @@ -143,7 +144,8 @@ proto._resumeMultipart = async function _resumeMultipart(checkpoint, options) {
let result;
try {
result = await self._uploadPart(name, uploadId, partNo, data, {
timeout: options.timeout
timeout: options.timeout,
disabledMD5: options.disabledMD5
});
} catch (error) {
if (error.status === 404) {
Expand Down
2 changes: 2 additions & 0 deletions lib/browser/object.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ proto.append = async function append(name, file, options) {
proto.put = async function put(name, file, options) {
let content;
options = options || {};
options.disabledMD5 = options.disabledMD5 === undefined ? true : !!options.disabledMD5;
options.headers = options.headers || {};
name = this._objectName(name);
if (isBuffer(file)) {
Expand All @@ -83,6 +84,7 @@ proto.put = async function put(name, file, options) {
const params = this._objectRequestParams(method, name, options);
callback.encodeCallback(params, options);
params.mime = options.mime;
params.disabledMD5 = options.disabledMD5;
params.content = content;
params.successStatuses = [200];

Expand Down
1 change: 1 addition & 0 deletions lib/common/multipart.js
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ proto._uploadPart = async function _uploadPart(name, uploadId, partNo, data, opt
const isBrowserEnv = process && process.browser;
isBrowserEnv ? (params.content = data.content) : (params.stream = data.stream);
params.successStatuses = [200];
params.disabledMD5 = options.disabledMD5;

const result = await this.request(params);

Expand Down
10 changes: 6 additions & 4 deletions lib/common/utils/createRequest.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,12 @@ function createRequest(params) {
delHeader(headers, 'Content-Type');
}
if (params.content) {
headers['Content-MD5'] = crypto
.createHash('md5')
.update(Buffer.from(params.content, 'utf8'))
.digest('base64');
if (!params.disabledMD5) {
headers['Content-MD5'] = crypto
.createHash('md5')
.update(Buffer.from(params.content, 'utf8'))
.digest('base64');
}
if (!headers['Content-Length']) {
headers['Content-Length'] = params.content.length;
}
Expand Down
10 changes: 6 additions & 4 deletions lib/common/utils/createRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,12 @@ export function createRequest(this: any, params) {
}

if (params.content) {
headers['Content-MD5'] = crypto
.createHash('md5')
.update(Buffer.from(params.content, 'utf8'))
.digest('base64');
if (!params.disabledMD5) {
headers['Content-MD5'] = crypto
.createHash('md5')
.update(Buffer.from(params.content, 'utf8'))
.digest('base64');
}
if (!headers['Content-Length']) {
headers['Content-Length'] = params.content.length;
}
Expand Down
44 changes: 42 additions & 2 deletions test/browser/browser.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -993,7 +993,6 @@ describe('browser', () => {
it('should signature url for PUT', async () => {
const putString = 'Hello World';
const contentMd5 = crypto1.createHash('md5').update(Buffer.from(putString, 'utf8')).digest('base64');
console.log(contentMd5);
const url = store.signatureUrl(name, {
method: 'PUT',
'Content-Type': 'text/plain; charset=UTF-8',
Expand Down Expand Up @@ -1731,7 +1730,6 @@ describe('browser', () => {
} catch (err) {
netErrs = err;
}
console.log(netErrs);
assert.strictEqual(netErrs.status, 0);
assert.strictEqual(netErrs.name, 'abort');
store._uploadPart = uploadPart;
Expand Down Expand Up @@ -2072,6 +2070,48 @@ describe('browser', () => {
});
});

describe('options.disabledMD5', () => {
const content = Array(100).fill(1).join('');
const body = new Blob([content], { type: 'text/plain' });
const MD5_VALUE = crypto1.createHash('md5').update(OSS.Buffer(content)).digest('base64');

it('should not calculate MD5 default when use put', async () => {
const store = oss(ossConfig);
const name = `${prefix}put/test-md5-0`;
const request = store.urllib.request;
let reqParams;
store.urllib.request = (url, params) => {
reqParams = params;
return request(url, params);
};
await store.put(name, body);
assert.strictEqual(reqParams.headers['Content-MD5'], undefined);
await store.put(name, body, { disabledMD5: false });
assert.strictEqual(reqParams.headers['Content-MD5'], MD5_VALUE);
store.urllib.request = request;
});

it('should not calculate MD5 default when use multipartUpload', async () => {
const store = oss(ossConfig);
const name = `${prefix}put/test-md5-2`;
const partSize = 100 * 1024;
const body2 = new File(Array(2 * partSize).fill(1), { type: 'text/plain' });
const request = store.urllib.request;
let headerWithMD5Count = 0;
store.urllib.request = (url, params) => {
if (params.headers['Content-MD5'] && /partNumber=\d/.test(url)) {
headerWithMD5Count++;
}
return request(url, params);
};
await store.multipartUpload(name, body2, { partSize });
assert.strictEqual(headerWithMD5Count, 0);
await store.multipartUpload(name, body2, { disabledMD5: false, partSize });
assert.strictEqual(headerWithMD5Count, 2);
store.urllib.request = request;
});
});

describe('test/retry.test.js', () => {
let store;
const RETRY_MAX = 3;
Expand Down

0 comments on commit 2d65189

Please sign in to comment.