Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(browser):copy object for browser #697

Merged
merged 1 commit into from
Dec 3, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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