UNPKG

9.66 kBJavaScriptView Raw
1
2
3const assert = require('assert');
4const { isArray } = require('./common/utils/isArray');
5const { checkBucketName: _checkBucketName } = require('../lib/common/utils/checkBucketName');
6const { formatTag } = require('../lib/common/utils/formatTag');
7
8const proto = exports;
9
10
11function toArray(obj) {
12 if (!obj) return [];
13 if (isArray(obj)) return obj;
14 return [obj];
15}
16
17/**
18 * Bucket opertaions
19 */
20
21proto.listBuckets = async function listBuckets(query = {}, options = {}) {
22 // prefix, marker, max-keys
23
24 const { subres = {} } = query;
25 const rest = {};
26 for (const key in query) {
27 if (key !== 'subres') {
28 rest[key] = query[key];
29 }
30 }
31 const params = this._bucketRequestParams(
32 'GET',
33 '',
34 Object.assign(subres, options.subres),
35 options
36 );
37
38 params.query = rest;
39
40 const result = await this.request(params);
41
42 if (result.status === 200) {
43 const data = await this.parseXML(result.data);
44 let buckets = data.Buckets || null;
45 if (buckets) {
46 if (buckets.Bucket) {
47 buckets = buckets.Bucket;
48 }
49 if (!isArray(buckets)) {
50 buckets = [buckets];
51 }
52 buckets = buckets.map(item => ({
53 name: item.Name,
54 region: item.Location,
55 creationDate: item.CreationDate,
56 StorageClass: item.StorageClass,
57 tag: formatTag(item)
58 }));
59 }
60 return {
61 buckets,
62 owner: {
63 id: data.Owner.ID,
64 displayName: data.Owner.DisplayName
65 },
66 isTruncated: data.IsTruncated === 'true',
67 nextMarker: data.NextMarker || null,
68 res: result.res
69 };
70 }
71
72 throw await this.requestError(result);
73};
74
75proto.useBucket = function useBucket(name) {
76 _checkBucketName(name);
77 return this.setBucket(name);
78};
79
80proto.setBucket = function useBucket(name) {
81 _checkBucketName(name);
82 this.options.bucket = name;
83 return this;
84};
85
86proto.getBucket = function getBucket() {
87 return this.options.bucket;
88};
89
90proto.getBucketLocation = async function getBucketLocation(name, options) {
91 _checkBucketName(name);
92 name = name || this.getBucket();
93 const params = this._bucketRequestParams('GET', name, 'location', options);
94 params.successStatuses = [200];
95 params.xmlResponse = true;
96 const result = await this.request(params);
97 return {
98 location: result.data,
99 res: result.res
100 };
101};
102
103proto.getBucketInfo = async function getBucketInfo(name, options) {
104 _checkBucketName(name);
105 name = name || this.getBucket();
106 const params = this._bucketRequestParams('GET', name, 'bucketInfo', options);
107 params.successStatuses = [200];
108 params.xmlResponse = true;
109 const result = await this.request(params);
110 return {
111 bucket: result.data.Bucket,
112 res: result.res
113 };
114};
115
116proto.deleteBucket = async function deleteBucket(name, options) {
117 _checkBucketName(name);
118 const params = this._bucketRequestParams('DELETE', name, '', options);
119 const result = await this.request(params);
120 if (result.status === 200 || result.status === 204) {
121 return {
122 res: result.res
123 };
124 }
125 throw await this.requestError(result);
126};
127
128// acl
129
130proto.putBucketACL = async function putBucketACL(name, acl, options) {
131 _checkBucketName(name);
132 const params = this._bucketRequestParams('PUT', name, 'acl', options);
133 params.headers = {
134 'x-oss-acl': acl
135 };
136 params.successStatuses = [200];
137 const result = await this.request(params);
138 return {
139 bucket: (result.headers.location && result.headers.location.substring(1)) || null,
140 res: result.res
141 };
142};
143
144proto.getBucketACL = async function getBucketACL(name, options) {
145 _checkBucketName(name);
146 const params = this._bucketRequestParams('GET', name, 'acl', options);
147 params.successStatuses = [200];
148 params.xmlResponse = true;
149 const result = await this.request(params);
150 return {
151 acl: result.data.AccessControlList.Grant,
152 owner: {
153 id: result.data.Owner.ID,
154 displayName: result.data.Owner.DisplayName
155 },
156 res: result.res
157 };
158};
159
160// logging
161
162proto.putBucketLogging = async function putBucketLogging(name, prefix, options) {
163 _checkBucketName(name);
164 const params = this._bucketRequestParams('PUT', name, 'logging', options);
165 let xml = `${'<?xml version="1.0" encoding="UTF-8"?>\n<BucketLoggingStatus>\n' +
166 '<LoggingEnabled>\n<TargetBucket>'}${name}</TargetBucket>\n`;
167 if (prefix) {
168 xml += `<TargetPrefix>${prefix}</TargetPrefix>\n`;
169 }
170 xml += '</LoggingEnabled>\n</BucketLoggingStatus>';
171 params.content = xml;
172 params.mime = 'xml';
173 params.successStatuses = [200];
174 const result = await this.request(params);
175 return {
176 res: result.res
177 };
178};
179
180proto.getBucketLogging = async function getBucketLogging(name, options) {
181 _checkBucketName(name);
182 const params = this._bucketRequestParams('GET', name, 'logging', options);
183 params.successStatuses = [200];
184 params.xmlResponse = true;
185 const result = await this.request(params);
186 const enable = result.data.LoggingEnabled;
187 return {
188 enable: !!enable,
189 prefix: (enable && enable.TargetPrefix) || null,
190 res: result.res
191 };
192};
193
194proto.deleteBucketLogging = async function deleteBucketLogging(name, options) {
195 _checkBucketName(name);
196 const params = this._bucketRequestParams('DELETE', name, 'logging', options);
197 params.successStatuses = [204, 200];
198 const result = await this.request(params);
199 return {
200 res: result.res
201 };
202};
203
204proto.putBucketCORS = async function putBucketCORS(name, rules, options) {
205 _checkBucketName(name);
206 rules = rules || [];
207 assert(rules.length, 'rules is required');
208 rules.forEach((rule) => {
209 assert(rule.allowedOrigin, 'allowedOrigin is required');
210 assert(rule.allowedMethod, 'allowedMethod is required');
211 });
212
213 const params = this._bucketRequestParams('PUT', name, 'cors', options);
214 let xml = '<?xml version="1.0" encoding="UTF-8"?>\n<CORSConfiguration>';
215 const parseOrigin = (val) => {
216 xml += `<AllowedOrigin>${val}</AllowedOrigin>`;
217 };
218 const parseMethod = (val) => {
219 xml += `<AllowedMethod>${val}</AllowedMethod>`;
220 };
221 const parseHeader = (val) => {
222 xml += `<AllowedHeader>${val}</AllowedHeader>`;
223 };
224 const parseExposeHeader = (val) => {
225 xml += `<ExposeHeader>${val}</ExposeHeader>`;
226 };
227 for (let i = 0, l = rules.length; i < l; i++) {
228 const rule = rules[i];
229 xml += '<CORSRule>';
230
231 toArray(rule.allowedOrigin).forEach(parseOrigin);
232 toArray(rule.allowedMethod).forEach(parseMethod);
233 toArray(rule.allowedHeader).forEach(parseHeader);
234 toArray(rule.exposeHeader).forEach(parseExposeHeader);
235 if (rule.maxAgeSeconds) {
236 xml += `<MaxAgeSeconds>${rule.maxAgeSeconds}</MaxAgeSeconds>`;
237 }
238 xml += '</CORSRule>';
239 }
240 xml += '</CORSConfiguration>';
241 params.content = xml;
242 params.mime = 'xml';
243 params.successStatuses = [200];
244 const result = await this.request(params);
245 return {
246 res: result.res
247 };
248};
249
250proto.getBucketCORS = async function getBucketCORS(name, options) {
251 _checkBucketName(name);
252 const params = this._bucketRequestParams('GET', name, 'cors', options);
253 params.successStatuses = [200];
254 params.xmlResponse = true;
255 const result = await this.request(params);
256 const rules = [];
257 if (result.data && result.data.CORSRule) {
258 let { CORSRule } = result.data;
259 if (!isArray(CORSRule)) CORSRule = [CORSRule];
260 CORSRule.forEach((rule) => {
261 const r = {};
262 Object.keys(rule).forEach((key) => {
263 r[key.slice(0, 1).toLowerCase() + key.slice(1, key.length)] = rule[key];
264 });
265 rules.push(r);
266 });
267 }
268 return {
269 rules,
270 res: result.res
271 };
272};
273
274proto.deleteBucketCORS = async function deleteBucketCORS(name, options) {
275 _checkBucketName(name);
276 const params = this._bucketRequestParams('DELETE', name, 'cors', options);
277 params.successStatuses = [204];
278 const result = await this.request(params);
279 return {
280 res: result.res
281 };
282};
283
284// referer
285
286proto.putBucketReferer = async function putBucketReferer(name, allowEmpty, referers, options) {
287 _checkBucketName(name);
288 const params = this._bucketRequestParams('PUT', name, 'referer', options);
289 let xml = '<?xml version="1.0" encoding="UTF-8"?>\n<RefererConfiguration>\n';
290 xml += ` <AllowEmptyReferer>${allowEmpty ? 'true' : 'false'}</AllowEmptyReferer>\n`;
291 if (referers && referers.length > 0) {
292 xml += ' <RefererList>\n';
293 for (let i = 0; i < referers.length; i++) {
294 xml += ` <Referer>${referers[i]}</Referer>\n`;
295 }
296 xml += ' </RefererList>\n';
297 } else {
298 xml += ' <RefererList />\n';
299 }
300 xml += '</RefererConfiguration>';
301 params.content = xml;
302 params.mime = 'xml';
303 params.successStatuses = [200];
304 const result = await this.request(params);
305 return {
306 res: result.res
307 };
308};
309
310proto.getBucketReferer = async function getBucketReferer(name, options) {
311 _checkBucketName(name);
312 const params = this._bucketRequestParams('GET', name, 'referer', options);
313 params.successStatuses = [200];
314 params.xmlResponse = true;
315 const result = await this.request(params);
316 let referers = result.data.RefererList.Referer || null;
317 if (referers) {
318 if (!isArray(referers)) {
319 referers = [referers];
320 }
321 }
322 return {
323 allowEmpty: result.data.AllowEmptyReferer === 'true',
324 referers,
325 res: result.res
326 };
327};
328
329proto.deleteBucketReferer = async function deleteBucketReferer(name, options) {
330 _checkBucketName(name);
331 return await this.putBucketReferer(name, true, null, options);
332};
333
334// private apis
335
336proto._bucketRequestParams = function _bucketRequestParams(method, bucket, subres, options) {
337 return {
338 method,
339 bucket,
340 subres,
341 timeout: options && options.timeout,
342 ctx: options && options.ctx
343 };
344};