Skip to content

Commit

Permalink
feat(browser):copy object for browser (#697)
Browse files Browse the repository at this point in the history
  • Loading branch information
PeterRao authored Dec 3, 2019
1 parent eb0cf58 commit 4faf0e8
Show file tree
Hide file tree
Showing 11 changed files with 244 additions and 137 deletions.
18 changes: 14 additions & 4 deletions lib/browser/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ const pkg = require('./version');
const dateFormat = require('dateformat');
const bowser = require('bowser');
const signUtils = require('../common/signUtils');
const utils = require('../common/utils');
const _isIP = require('../common/utils/isIP');
const _checkBucketName = require('../common/utils/checkBucketName');
const _initOptions = require('../common/client/initOptions');

const globalHttpAgent = new AgentKeepalive();
Expand Down Expand Up @@ -93,7 +94,18 @@ merge(proto, require('./object'));
// /**
// * Bucket operations
// */
/**
* check Bucket Name
*/

proto._checkBucketName = function (name) {
if (!_checkBucketName(name)) {
throw new Error('The bucket must be conform to the specifications');
}
};
// merge(proto, require('./bucket'));


// multipart upload
merge(proto, require('./managed-upload'));
/**
Expand Down Expand Up @@ -281,9 +293,7 @@ proto._getResource = function _getResource(params) {
return resource;
};

proto._isIP = function _isIP(host) {
return utils._isIP(host);
};
proto._isIP = _isIP;

proto._escape = function _escape(name) {
return utility.encodeURIComponent(name).replace(/%2F/g, '/');
Expand Down
43 changes: 2 additions & 41 deletions lib/browser/object.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const path = require('path');
const mime = require('mime');
const callback = require('../common/callback');
const signHelper = require('../common/signUtils');
const merge = require('merge-descriptors');

// var assert = require('assert');

Expand Down Expand Up @@ -273,47 +274,7 @@ proto.deleteMulti = async function deleteMulti(names, options) {
};
};

/* eslint no-shadow: [0] */
proto.copy = async function copy(name, sourceName, options) {
options = options || {};
options.headers = options.headers || {};
Object.keys(options.headers).forEach((key) => {
options.headers[`x-oss-copy-source-${key.toLowerCase()}`] = options.headers[key];
});

if (options.meta) {
options.headers['x-oss-metadata-directive'] = 'REPLACE';
}
this._convertMetaToHeaders(options.meta, options.headers);

if (sourceName[0] !== '/') {
// no specify bucket name
sourceName = `/${this.options.bucket}/${encodeURIComponent(sourceName)}`;
} else {
sourceName = `/${encodeURIComponent(sourceName.slice(1))}`;
}

options.headers['x-oss-copy-source'] = sourceName;

const params = this._objectRequestParams('PUT', name, options);
params.xmlResponse = true;
params.successStatuses = [200, 304];

const result = await this.request(params);

let { data } = result;
if (data) {
data = {
etag: data.ETag,
lastModified: data.LastModified
};
}

return {
data,
res: result.res
};
};
merge(proto, require('../common/object/copyObject'));

proto.putMeta = async function putMeta(name, meta, options) {
const copyResult = await this.copy(name, name, {
Expand Down
6 changes: 3 additions & 3 deletions lib/bucket.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@


const assert = require('assert');
const utils = require('./common/utils/checkBucketName');
const _checkBucketName = require('./common/utils/checkBucketName');

const proto = exports;

Expand All @@ -21,8 +21,8 @@ function toArray(obj) {
* check Bucket Name
*/

proto._checkBucketName = function _checkBucketName(name) {
if (!utils._checkBucketName(name)) {
proto._checkBucketName = function (name) {
if (!_checkBucketName(name)) {
throw new Error('The bucket must be conform to the specifications');
}
};
Expand Down
6 changes: 2 additions & 4 deletions lib/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const pkg = require('../package.json');
const dateFormat = require('dateformat');
const bowser = require('bowser');
const signUtils = require('./common/signUtils');
const utils = require('./common/utils');
const _isIP = require('./common/utils/isIP');
const _initOptions = require('./common/client/initOptions');

const globalHttpAgent = new AgentKeepalive();
Expand Down Expand Up @@ -285,9 +285,7 @@ proto._getResource = function _getResource(params) {
return resource;
};

proto._isIP = function _isIP(host) {
return utils._isIP(host);
};
proto._isIP = _isIP;

proto._escape = function _escape(name) {
return utility.encodeURIComponent(name).replace(/%2F/g, '/');
Expand Down
4 changes: 2 additions & 2 deletions lib/common/bucket/putBucketRequestPayment.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const utils = require('../utils/index.js');
const obj2xml = require('../utils/obj2xml');

const proto = exports;
/**
Expand Down Expand Up @@ -33,7 +33,7 @@ proto.putBucketRequestPayment = async function putBucketRequestPayment(
Payer: payer
}
};
const paramXML = utils.obj2xml(paramXMLObj, {
const paramXML = obj2xml(paramXMLObj, {
headers: true
});

Expand Down
2 changes: 1 addition & 1 deletion lib/common/utils/checkBucketName.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* check Bucket Name
*/

exports._checkBucketName = function (name) {
module.exports = function (name) {
const bucketRegex = /^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$/;
const checkBucket = bucketRegex.test(name);
return checkBucket;
Expand Down
7 changes: 0 additions & 7 deletions lib/common/utils/index.js

This file was deleted.

4 changes: 1 addition & 3 deletions lib/common/utils.js → lib/common/utils/isIP.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 1 addition & 3 deletions lib/common/utils/obj2xml.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,4 @@ function obj2xml(obj, options) {
return s;
}

module.exports = {
obj2xml
};
module.exports = obj2xml;
153 changes: 152 additions & 1 deletion test/browser/browser.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const md5 = require('crypto-js/md5');
const stsConfig = require('./.tmp/stsConfig.json');
const pkg = require('../../package.json');
const platform = require('platform');
const { callbackServer } = require('../../test/const');
// const { callbackServer } = require('../../test/const');

const crypto1 = require('crypto');
const { prefix } = require('./browser-utils');
Expand Down Expand Up @@ -556,6 +556,157 @@ describe('browser', () => {
});
});

describe('copy()', () => {
let name;
// let resHeaders;
// const otherBucket = '';
// let otherBucketObject;
let store;
before(async () => {
name = `${prefix}ali-sdk/oss/copy-meta.js`;
store = oss(ossConfig);
const object = await store.put(name, new Buffer('abc'), {
meta: {
uid: 1,
pid: '123',
slus: 'test.html'
}
});
assert.equal(typeof object.res.headers['x-oss-request-id'], 'string');
});

it('should copy object from same bucket', async () => {
const originname = `${prefix}ali-sdk/oss/copy-new.js`;
const result = await store.copy(originname, name);
assert.equal(result.res.status, 200);
assert.equal(typeof result.data.etag, 'string');
assert.equal(typeof result.data.lastModified, 'string');

const info = await store.head(originname);
// Must set CORS
// assert.equal(info.meta.uid, '1');
// assert.equal(info.meta.pid, '123');
// assert.equal(info.meta.slus, 'test.html');
assert.equal(info.status, 200);
});

it.skip('should copy object from other bucket, sourceBucket in copySource', async () => {
const copySource = `/${otherBucket}/${otherBucketObject}`;
const copyTarget = `${prefix}ali-sdk/oss/copy-target.js`;
const result = await store.copy(copyTarget, copySource);
assert.equal(result.res.status, 200);

const info = await store.head(copyTarget);
assert.equal(info.status, 200);
});

it.skip('should copy object from other bucket, sourceBucket is a separate parameter', async () => {
const copySource = otherBucketObject;
const copyTarget = `${prefix}ali-sdk/oss/has-bucket-name-copy-target.js`;
const result = await store.copy(copyTarget, copySource, otherBucket);
assert.equal(result.res.status, 200);

const info = await store.head(copyTarget);
assert.equal(info.status, 200);
});

it('should copy object with non-english name', async () => {
const sourceName = `${prefix}ali-sdk/oss/copy-meta_测试.js`;
let result = await store.put(sourceName, new Buffer('abc'), {
meta: {
uid: 2,
pid: '1234',
slus: 'test1.html'
}
});

const originname = `${prefix}ali-sdk/oss/copy-new_测试.js`;
result = await store.copy(originname, sourceName);
assert.equal(result.res.status, 200);
assert.equal(typeof result.data.etag, 'string');
assert.equal(typeof result.data.lastModified, 'string');

const info = await store.head(originname);
// Must set CORS
// assert.equal(info.meta.uid, '2');
// assert.equal(info.meta.pid, '1234');
// assert.equal(info.meta.slus, 'test1.html');
assert.equal(info.status, 200);
});

it.skip('should copy object with non-english name and bucket', async () => {
let sourceName = `${prefix}ali-sdk/oss/copy-meta_测试2.js`;
let result = await store.put(sourceName, __filename, {
meta: {
uid: 3,
pid: '12345',
slus: 'test2.html'
}
});

let info = await store.head(sourceName);
assert.equal(info.meta.uid, '3');
assert.equal(info.meta.pid, '12345');
assert.equal(info.meta.slus, 'test2.html');
assert.equal(info.status, 200);

sourceName = `/${bucket}/${sourceName}`;
const originname = `${prefix}ali-sdk/oss/copy-new_测试2.js`;
result = await store.copy(originname, sourceName);
assert.equal(result.res.status, 200);
assert.equal(typeof result.data.etag, 'string');
assert.equal(typeof result.data.lastModified, 'string');

info = await store.head(originname);
// Must set CORS
// assert.equal(info.meta.uid, '3');
// assert.equal(info.meta.pid, '12345');
// assert.equal(info.meta.slus, 'test2.html');
assert.equal(info.status, 200);
});

it('should copy object and set other meta', async () => {
const originname = `${prefix}ali-sdk/oss/copy-new-2.js`;
const result = await store.copy(originname, name, {
meta: {
uid: '2'
}
});
assert.equal(result.res.status, 200);
assert.equal(typeof result.data.etag, 'string');
assert.equal(typeof result.data.lastModified, 'string');

const info = await store.head(originname);
// Must set CORS
// assert.equal(info.meta.uid, '2');
// assert(!info.meta.pid);
// assert(!info.meta.slus);
assert.equal(info.status, 200);
});

it('should use copy to change exists object headers', async () => {
const originname = `${prefix}ali-sdk/oss/copy-new-3.js`;
let result = await store.copy(originname, name);
assert.equal(result.res.status, 200);
assert.equal(typeof result.data.etag, 'string');
assert.equal(typeof result.data.lastModified, 'string');
let info = await store.head(originname);
assert(!info.res.headers['cache-control']);

// add Cache-Control header to a exists object
result = await store.copy(originname, originname, {
headers: {
'Cache-Control': 'max-age=0, s-maxage=86400'
}
});
assert.equal(result.res.status, 200);
assert.equal(typeof result.data.etag, 'string');
assert.equal(typeof result.data.lastModified, 'string');
info = await store.head(originname);
assert.equal(info.res.headers['cache-control'], 'max-age=0, s-maxage=86400');
});
});

describe('signatureUrl()', () => {
let store;
let name;
Expand Down
Loading

0 comments on commit 4faf0e8

Please sign in to comment.