Skip to content

Commit e1cb438

Browse files
authored
feat: putBucketWebsite support new parameter (#736)
1 parent 02d59da commit e1cb438

File tree

10 files changed

+214
-106
lines changed

10 files changed

+214
-106
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,9 @@ parameters:
638638
- config {Object} website config, contains blow properties:
639639
- index {String} default page, e.g.: `index.html`
640640
- [error] {String} error page, e.g.: 'error.html'
641+
- [supportSubDir] {String} default vaule false
642+
- [type] {String} default value 0
643+
- [routingRules] {Array} RoutingRules
641644
- [options] {Object} optional parameters
642645
- [timeout] {Number} the operation timeout
643646

@@ -672,6 +675,9 @@ Success will return:
672675

673676
- index {String} index page
674677
- error {String} error page, maybe `null`
678+
- supportSubDir {String}
679+
- type {String}
680+
- routingRules {Array}
675681
- res {Object} response info, including
676682
- status {Number} response status
677683
- headers {Object} response headers

lib/browser/bucket.js

Lines changed: 0 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -159,49 +159,6 @@ proto.deleteBucketLogging = async function deleteBucketLogging(name, options) {
159159
};
160160
};
161161

162-
// website
163-
164-
proto.putBucketWebsite = async function putBucketWebsite(name, config, options) {
165-
// config: index, [error]
166-
const params = this._bucketRequestParams('PUT', name, 'website', options);
167-
config = config || {};
168-
config.index = config.index || 'index.html';
169-
let xml = `${'<?xml version="1.0" encoding="UTF-8"?>\n<WebsiteConfiguration>\n' +
170-
' <IndexDocument><Suffix>'}${config.index}</Suffix></IndexDocument>\n`;
171-
if (config.error) {
172-
xml += `<ErrorDocument><Key>${config.error}</Key></ErrorDocument>\n`;
173-
}
174-
xml += '</WebsiteConfiguration>';
175-
params.content = xml;
176-
params.mime = 'xml';
177-
params.successStatuses = [200];
178-
const result = await this.request(params);
179-
return {
180-
res: result.res
181-
};
182-
};
183-
184-
proto.getBucketWebsite = async function getBucketWebsite(name, options) {
185-
const params = this._bucketRequestParams('GET', name, 'website', options);
186-
params.successStatuses = [200];
187-
params.xmlResponse = true;
188-
const result = await this.request(params);
189-
return {
190-
index: result.data.IndexDocument.Suffix,
191-
error: (result.data.ErrorDocument && result.data.ErrorDocument.Key) || null,
192-
res: result.res
193-
};
194-
};
195-
196-
proto.deleteBucketWebsite = async function deleteBucketWebsite(name, options) {
197-
const params = this._bucketRequestParams('DELETE', name, 'website', options);
198-
params.successStatuses = [204];
199-
const result = await this.request(params);
200-
return {
201-
res: result.res
202-
};
203-
};
204-
205162
// lifecycle
206163

207164
proto.putBucketLifecycle = async function putBucketLifecycle(name, rules, options) {

lib/browser/client.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,12 @@ proto.debug = debug;
9898
* Object operations
9999
*/
100100
merge(proto, require('./object'));
101-
// /**
102-
// * Bucket operations
103-
// */
101+
/**
102+
* Bucket operations
103+
*/
104+
merge(proto, require('../common/bucket/getBucketWebsite'));
105+
merge(proto, require('../common/bucket/putBucketWebsite'));
106+
merge(proto, require('../common/bucket/deleteBucketWebsite'));
104107

105108
// merge(proto, require('./bucket'));
106109

lib/bucket.js

Lines changed: 1 addition & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
11

22

33
const assert = require('assert');
4+
const isArray = require('./common/utils/isArray');
45

56
const proto = exports;
67

78

8-
function isArray(arr) {
9-
if (Array.isArray) return Array.isArray(arr);
10-
return Object.prototype.toString.call(arr) === '[object Array]';
11-
}
12-
139
function toArray(obj) {
1410
if (!obj) return [];
1511
if (isArray(obj)) return obj;
@@ -190,52 +186,6 @@ proto.deleteBucketLogging = async function deleteBucketLogging(name, options) {
190186
};
191187
};
192188

193-
// website
194-
195-
proto.putBucketWebsite = async function putBucketWebsite(name, config, options) {
196-
this._checkBucketName(name);
197-
// config: index, [error]
198-
const params = this._bucketRequestParams('PUT', name, 'website', options);
199-
config = config || {};
200-
config.index = config.index || 'index.html';
201-
let xml = `${'<?xml version="1.0" encoding="UTF-8"?>\n<WebsiteConfiguration>\n' +
202-
' <IndexDocument><Suffix>'}${config.index}</Suffix></IndexDocument>\n`;
203-
if (config.error) {
204-
xml += `<ErrorDocument><Key>${config.error}</Key></ErrorDocument>\n`;
205-
}
206-
xml += '</WebsiteConfiguration>';
207-
params.content = xml;
208-
params.mime = 'xml';
209-
params.successStatuses = [200];
210-
const result = await this.request(params);
211-
return {
212-
res: result.res
213-
};
214-
};
215-
216-
proto.getBucketWebsite = async function getBucketWebsite(name, options) {
217-
this._checkBucketName(name);
218-
const params = this._bucketRequestParams('GET', name, 'website', options);
219-
params.successStatuses = [200];
220-
params.xmlResponse = true;
221-
const result = await this.request(params);
222-
return {
223-
index: result.data.IndexDocument.Suffix,
224-
error: (result.data.ErrorDocument && result.data.ErrorDocument.Key) || null,
225-
res: result.res
226-
};
227-
};
228-
229-
proto.deleteBucketWebsite = async function deleteBucketWebsite(name, options) {
230-
this._checkBucketName(name);
231-
const params = this._bucketRequestParams('DELETE', name, 'website', options);
232-
params.successStatuses = [204];
233-
const result = await this.request(params);
234-
return {
235-
res: result.res
236-
};
237-
};
238-
239189
// lifecycle
240190

241191
proto.putBucketLifecycle = async function putBucketLifecycle(name, rules, options) {
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
const proto = exports;
2+
3+
proto.deleteBucketWebsite = async function deleteBucketWebsite(name, options) {
4+
this._checkBucketName(name);
5+
const params = this._bucketRequestParams('DELETE', name, 'website', options);
6+
params.successStatuses = [204];
7+
const result = await this.request(params);
8+
return {
9+
res: result.res
10+
};
11+
};
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
const isObject = require('../utils/isObject');
2+
3+
const proto = exports;
4+
5+
proto.getBucketWebsite = async function getBucketWebsite(name, options) {
6+
this._checkBucketName(name);
7+
const params = this._bucketRequestParams('GET', name, 'website', options);
8+
params.successStatuses = [200];
9+
params.xmlResponse = true;
10+
const result = await this.request(params);
11+
let routingRules = [];
12+
if (result.data.RoutingRules && result.data.RoutingRules.RoutingRule) {
13+
if (isObject(result.data.RoutingRules.RoutingRule)) {
14+
routingRules = [result.data.RoutingRules.RoutingRule];
15+
} else {
16+
routingRules = result.data.RoutingRules.RoutingRule;
17+
}
18+
}
19+
return {
20+
index: (result.data.IndexDocument && result.data.IndexDocument.Suffix) || '',
21+
supportSubDir: (result.data.IndexDocument && result.data.IndexDocument.SupportSubDir) || 'false',
22+
type: (result.data.IndexDocument && result.data.IndexDocument.Type),
23+
routingRules,
24+
error: (result.data.ErrorDocument && result.data.ErrorDocument.Key) || null,
25+
res: result.res
26+
};
27+
};

lib/common/bucket/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,6 @@ merge(proto, require('./putBucketTags'));
1212
merge(proto, require('./deleteBucketTags'));
1313
merge(proto, require('./putBucket'));
1414
merge(proto, require('./_checkBucketName'));
15+
merge(proto, require('./getBucketWebsite'));
16+
merge(proto, require('./putBucketWebsite'));
17+
merge(proto, require('./deleteBucketWebsite'));
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
const obj2xml = require('../utils/obj2xml');
2+
const isArray = require('../utils/isArray');
3+
4+
const proto = exports;
5+
proto.putBucketWebsite = async function putBucketWebsite(name, config = {}, options) {
6+
this._checkBucketName(name);
7+
const params = this._bucketRequestParams('PUT', name, 'website', options);
8+
const IndexDocument = {
9+
Suffix: config.index || 'index.html'
10+
};
11+
const WebsiteConfiguration = {
12+
IndexDocument
13+
};
14+
let website = {
15+
WebsiteConfiguration
16+
};
17+
18+
if (config.supportSubDir) {
19+
IndexDocument.SupportSubDir = config.supportSubDir;
20+
}
21+
22+
if (config.type) {
23+
IndexDocument.Type = config.type;
24+
}
25+
26+
if (config.error) {
27+
WebsiteConfiguration.ErrorDocument = {
28+
Key: config.error
29+
};
30+
}
31+
32+
if (config.routingRules !== undefined) {
33+
if (!isArray(config.routingRules)) {
34+
throw new Error('RoutingRules must be Array');
35+
}
36+
WebsiteConfiguration.RoutingRules = {
37+
RoutingRule: config.routingRules
38+
};
39+
}
40+
41+
website = obj2xml(website);
42+
params.content = website;
43+
params.mime = 'xml';
44+
params.successStatuses = [200];
45+
const result = await this.request(params);
46+
return {
47+
res: result.res
48+
};
49+
};

lib/common/utils/isArray.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = function isArray(obj) {
2+
return Object.prototype.toString.call(obj) === '[object Array]';
3+
};

test/node/bucket.test.js

Lines changed: 108 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -251,17 +251,10 @@ describe('test/bucket.test.js', () => {
251251
});
252252

253253
describe('putBucketWebsite(), getBucketWebsite(), deleteBucketWebsite()', () => {
254-
it('should create, get and delete the website settings', async () => {
255-
const result1 = await store.putBucketWebsite(bucket, {
254+
it('should get and delete the website settings', async () => {
255+
await store.putBucketWebsite(bucket, {
256256
index: 'index.html'
257257
});
258-
assert.equal(result1.res.status, 200);
259-
// put again will be fine
260-
const result2 = await store.putBucketWebsite(bucket, {
261-
index: 'index.htm',
262-
error: 'error.htm'
263-
});
264-
assert.equal(result2.res.status, 200);
265258

266259
await utils.sleep(ms(metaSyncTime));
267260

@@ -274,6 +267,112 @@ describe('test/bucket.test.js', () => {
274267
const del = await store.deleteBucketWebsite(bucket);
275268
assert.equal(del.res.status, 204);
276269
});
270+
271+
it('should create when RoutingRules is Array or Object', async () => {
272+
const routingRule1 = {
273+
RuleNumber: '1',
274+
Condition: {
275+
KeyPrefixEquals: 'abc/',
276+
HttpErrorCodeReturnedEquals: '404'
277+
},
278+
Redirect: {
279+
RedirectType: 'Mirror',
280+
MirrorUsingRole: 'false',
281+
MirrorUserLastModified: 'false',
282+
PassQueryString: 'true',
283+
MirrorIsExpressTunnel: 'false',
284+
MirrorPassOriginalSlashes: 'false',
285+
MirrorAllowHeadObject: 'false',
286+
MirrorURL: 'http://www.test.com/',
287+
MirrorPassQueryString: 'true',
288+
MirrorFollowRedirect: 'true',
289+
MirrorCheckMd5: 'true',
290+
MirrorHeaders: {
291+
PassAll: 'true',
292+
Pass: ['myheader-key1', 'myheader-key2'],
293+
Remove: ['remove1', 'remove2'],
294+
Set: {
295+
Key: 'myheader-key5',
296+
Value: 'myheader-value5'
297+
}
298+
}
299+
}
300+
};
301+
const routingRules = [
302+
{
303+
RuleNumber: '2',
304+
Condition: {
305+
KeyPrefixEquals: 'a1bc/',
306+
HttpErrorCodeReturnedEquals: '404'
307+
},
308+
Redirect: {
309+
RedirectType: 'Mirror',
310+
MirrorUsingRole: 'false',
311+
MirrorUserLastModified: 'false',
312+
MirrorAllowHeadObject: 'false',
313+
MirrorIsExpressTunnel: 'false',
314+
MirrorPassOriginalSlashes: 'false',
315+
PassQueryString: 'true',
316+
MirrorURL: 'http://www.test1.com/',
317+
MirrorPassQueryString: 'true',
318+
MirrorFollowRedirect: 'true',
319+
MirrorCheckMd5: 'true',
320+
MirrorHeaders: {
321+
PassAll: 'true',
322+
Pass: ['myheader-key12', 'myheader-key22'],
323+
Remove: ['remove1', 'remove2'],
324+
Set: {
325+
Key: 'myheader-key5',
326+
Value: 'myheader-value5'
327+
}
328+
}
329+
}
330+
}];
331+
const website = {
332+
index: 'index1.html',
333+
supportSubDir: 'true',
334+
type: '1',
335+
error: 'error1.html',
336+
routingRules
337+
};
338+
339+
const result1 = await store.putBucketWebsite(bucket, website);
340+
assert.strictEqual(result1.res.status, 200);
341+
const rules1 = await store.getBucketWebsite(bucket);
342+
assert.deepStrictEqual(rules1.routingRules, routingRules);
343+
assert.strictEqual(rules1.supportSubDir, website.supportSubDir);
344+
assert.strictEqual(rules1.type, website.type);
345+
346+
website.routingRules = [routingRule1];
347+
const result2 = await store.putBucketWebsite(bucket, website);
348+
assert.strictEqual(result2.res.status, 200);
349+
const rules2 = await store.getBucketWebsite(bucket);
350+
assert.deepStrictEqual(rules2.routingRules, website.routingRules);
351+
});
352+
353+
it('should throw error when RoutingRules is not Array', async () => {
354+
const website = {
355+
index: 'index1.html',
356+
supportSubDir: 'true',
357+
type: '1',
358+
error: 'error1.html',
359+
routingRules: ''
360+
};
361+
362+
try {
363+
await store.putBucketWebsite(bucket, website);
364+
assert(false);
365+
} catch (error) {
366+
assert.strictEqual(error.message, 'RoutingRules must be Array');
367+
}
368+
try {
369+
website.RoutingRules = 0;
370+
await store.putBucketWebsite(bucket, website);
371+
assert(false);
372+
} catch (error) {
373+
assert.strictEqual(error.message, 'RoutingRules must be Array');
374+
}
375+
});
277376
});
278377

279378
describe('putBucketLifecycle(), getBucketLifecycle(), deleteBucketLifecycle()', () => {

0 commit comments

Comments
 (0)