Skip to content

Commit 6833dde

Browse files
committed
CLDSRV-848: x-amz-checksum-[crc64nvme, crc32, crc32C, sha1, sha256] functional tests
1 parent 0a01938 commit 6833dde

File tree

1 file changed

+319
-0
lines changed

1 file changed

+319
-0
lines changed
Lines changed: 319 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,319 @@
1+
const assert = require('assert');
2+
const HttpRequestAuthV4 = require('../utils/HttpRequestAuthV4');
3+
4+
const bucket = 'xxx';
5+
const objectKey = 'key';
6+
const objData = Buffer.alloc(1, 'a');
7+
8+
const authCredentials = {
9+
accessKey: 'accessKey1',
10+
secretKey: 'verySecretKey1',
11+
};
12+
13+
const itSkipIfAWS = process.env.AWS_ON_AIR ? it.skip : it;
14+
15+
describe('Test x-amz-checksums', () => {
16+
const algos = [
17+
{ name: 'CRC32', objDataDigest: '6Le+Qw==', validWrong: 'AAAAAA==' },
18+
{ name: 'CRC32C', objDataDigest: 'wdBDMA==', validWrong: 'AAAAAA==' },
19+
{ name: 'CRC64NVME', objDataDigest: 'jC+ERbTL/Dw=', validWrong: 'AAAAAAAAAAA=' },
20+
{ name: 'SHA1', objDataDigest: 'hvfkN/qlp/zhXR3cuerq6jd2Z7g=', validWrong: 'AAAAAAAAAAAAAAAAAAAAAAAAAAA=' },
21+
{
22+
name: 'SHA256', objDataDigest: 'ypeBEsobvcr6wjGzmiPcTaeG7/gUfE5yuYB3ha/uSLs=',
23+
validWrong: 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA='
24+
},
25+
];
26+
const methods = [
27+
{
28+
Name: 'CompleteMultipartupload',
29+
Query: 'uploadId=77a4ce46b9bf4ea69d9e0cc3f0bb1aae',
30+
Key: objectKey,
31+
HTTPMethod: 'POST',
32+
},
33+
{
34+
Name: 'DeleteObjects',
35+
Query: 'delete',
36+
Key: '',
37+
HTTPMethod: 'POST',
38+
},
39+
{
40+
Name: 'PutBucketACL',
41+
Query: 'acl',
42+
Key: '',
43+
HTTPMethod: 'PUT',
44+
},
45+
{
46+
Name: 'PutBucketACL',
47+
Query: 'cors',
48+
Key: '',
49+
HTTPMethod: 'PUT',
50+
},
51+
{
52+
Name: 'PutBucketEncryption',
53+
Query: 'encryption',
54+
Key: '',
55+
HTTPMethod: 'PUT',
56+
},
57+
{
58+
Name: 'PutBucketLifecycke',
59+
Query: 'lifecycle',
60+
Key: '',
61+
HTTPMethod: 'PUT',
62+
},
63+
{
64+
Name: 'PutBucketLogging',
65+
Query: 'logging',
66+
Key: '',
67+
HTTPMethod: 'PUT',
68+
},
69+
{
70+
Name: 'PutBucketNotification',
71+
Query: 'notification',
72+
Key: '',
73+
HTTPMethod: 'PUT',
74+
},
75+
{
76+
Name: 'PutBucketPolicy',
77+
Query: 'policy',
78+
Key: '',
79+
HTTPMethod: 'PUT',
80+
},
81+
{
82+
Name: 'PutBucketReplication',
83+
Query: 'replication',
84+
Key: '',
85+
HTTPMethod: 'PUT',
86+
},
87+
{
88+
Name: 'PutBucketTagging',
89+
Query: 'tagging',
90+
Key: '',
91+
HTTPMethod: 'PUT',
92+
},
93+
{
94+
Name: 'PutBucketVersioning',
95+
Query: 'versioning',
96+
Key: '',
97+
HTTPMethod: 'PUT',
98+
},
99+
{
100+
Name: 'PutBucketWebsite',
101+
Query: 'website',
102+
Key: '',
103+
HTTPMethod: 'PUT',
104+
},
105+
{
106+
Name: 'PutObjectACL',
107+
Query: 'acl',
108+
Key: objectKey,
109+
HTTPMethod: 'PUT',
110+
},
111+
{
112+
Name: 'PutObjectLegalHold',
113+
Query: 'legal-hold',
114+
Key: objectKey,
115+
HTTPMethod: 'PUT',
116+
},
117+
{
118+
Name: 'PutObjectLockConfiguration',
119+
Query: 'object-lock',
120+
Key: '',
121+
HTTPMethod: 'PUT',
122+
},
123+
{
124+
Name: 'PutObjectRetention',
125+
Query: 'retention',
126+
Key: objectKey,
127+
HTTPMethod: 'PUT',
128+
},
129+
{
130+
Name: 'PutObjectTagging',
131+
Query: 'tagging',
132+
Key: objectKey,
133+
HTTPMethod: 'PUT',
134+
},
135+
{
136+
Name: 'RestoreObject',
137+
Query: 'restore',
138+
Key: objectKey,
139+
HTTPMethod: 'POST',
140+
},
141+
];
142+
143+
const doTest = (headers, method, resHTTPStatus, errMsgs, done) => {
144+
const url = `http://localhost:8000/${bucket}/${method.Key}?${method.Query}`;
145+
const req = new HttpRequestAuthV4(
146+
url,
147+
Object.assign(
148+
{
149+
method: method.HTTPMethod,
150+
headers: {
151+
'x-amz-content-sha256': 'ypeBEsobvcr6wjGzmiPcTaeG7/gUfE5yuYB3ha/uSLs=',
152+
'content-length': objData.length,
153+
...headers,
154+
},
155+
},
156+
authCredentials
157+
),
158+
res => {
159+
let data = '';
160+
res.on('data', chunk => {
161+
data += chunk;
162+
});
163+
res.on('end', () => {
164+
assert.strictEqual(res.statusCode, resHTTPStatus);
165+
for (const errMsg of errMsgs) {
166+
assert(data.includes(errMsg), `missing ${errMsg} in "${data}"`);
167+
}
168+
done();
169+
});
170+
}
171+
);
172+
173+
req.on('error', err => {
174+
assert.ifError(err);
175+
});
176+
177+
178+
req.once('drain', () => {
179+
req.end();
180+
});
181+
182+
req.write(objData, err => {
183+
assert.ifError(err);
184+
req.end();
185+
});
186+
};
187+
188+
for (const algo of algos) {
189+
for (const method of methods) {
190+
itSkipIfAWS(
191+
`${method.Name} should respond BadDigest ` +
192+
`with invalid x-amz-checksum-${algo.name.toLowerCase()}`, done => {
193+
const headers = {
194+
[`x-amz-checksum-${algo.name.toLowerCase()}`]: algo.validWrong,
195+
};
196+
doTest(headers, method, 400, ['BadDigest'], done);
197+
});
198+
}
199+
}
200+
201+
itSkipIfAWS('should respond InvalidRequest with multiple x-amz-checksum-', done => {
202+
const headers = {
203+
[`x-amz-checksum-${algos[0].name.toLowerCase()}`]: algos[0].objDataDigest,
204+
[`x-amz-checksum-${algos[1].name.toLowerCase()}`]: algos[1].objDataDigest,
205+
};
206+
doTest(
207+
headers,
208+
methods[0],
209+
400,
210+
['InvalidRequest', 'Expecting a single x-amz-checksum- header. Multiple checksum Types are not allowed.'],
211+
done,
212+
);
213+
});
214+
215+
itSkipIfAWS('should respond InvalidRequest with if invalid x-amz-checksum- algorithm', done => {
216+
const headers = {
217+
['x-amz-checksum-BAD']: algos[0].objDataDigest,
218+
};
219+
doTest(
220+
headers,
221+
methods[0],
222+
400,
223+
['InvalidRequest', 'The algorithm type you specified in x-amz-checksum- header is invalid'],
224+
done,
225+
);
226+
});
227+
228+
itSkipIfAWS(
229+
'should respond InvalidRequest if the value of x-amz-sdk-checksum-algorithm is invalid', done => {
230+
const headers = {
231+
'x-amz-sdk-checksum-algorithm': 'BAD',
232+
[`x-amz-checksum-${algos[0].name.toLowerCase()}`]: algos[0].objDataDigest,
233+
};
234+
doTest(
235+
headers,
236+
methods[0],
237+
400,
238+
['InvalidRequest', 'Value for x-amz-sdk-checksum-algorithm header is invalid.'],
239+
done,
240+
);
241+
});
242+
243+
itSkipIfAWS('should respond InvalidRequest with if invalid x-amz-checksum- value', done => {
244+
const headers = {
245+
['x-amz-checksum-sha256']: 'BAD',
246+
};
247+
doTest(
248+
headers,
249+
methods[0],
250+
400,
251+
['InvalidRequest', 'Value for x-amz-checksum-sha256 header is invalid.'],
252+
done,
253+
);
254+
});
255+
256+
itSkipIfAWS(
257+
'should respond InvalidRequest with if missing x-amz-checksum- for x-amz-sdk-checksum-algorithm ', done => {
258+
const headers = {
259+
'x-amz-sdk-checksum-algorithm': 'SHA1',
260+
};
261+
doTest(
262+
headers,
263+
methods[0],
264+
400,
265+
['InvalidRequest', 'x-amz-sdk-checksum-algorithm specified, but no corresponding x-amz-checksum-* ' +
266+
'or x-amz-trailer headers were found.'],
267+
done,
268+
);
269+
});
270+
271+
for (const algo of algos) {
272+
for (const method of methods) {
273+
itSkipIfAWS(
274+
`${method.Name} should not respond BadDigest if ` +
275+
`x-amz-checksum-${algo.name.toLowerCase()} is correct`, done => {
276+
const url = `http://localhost:8000/${bucket}/${method.Key}?${method.Query}`;
277+
const req = new HttpRequestAuthV4(
278+
url,
279+
Object.assign(
280+
{
281+
method: method.HTTPMethod,
282+
headers: {
283+
'x-amz-content-sha256': 'ypeBEsobvcr6wjGzmiPcTaeG7/gUfE5yuYB3ha/uSLs=',
284+
'content-length': objData.length,
285+
'x-amz-sdk-checksum-algorithm': algo.name,
286+
[`x-amz-checksum-${algo.name.toLowerCase()}`]: algo.objDataDigest,
287+
},
288+
},
289+
authCredentials
290+
),
291+
res => {
292+
let data = '';
293+
res.on('data', chunk => {
294+
data += chunk;
295+
});
296+
res.on('end', () => {
297+
assert(!data.includes('BadDigest'));
298+
done();
299+
});
300+
}
301+
);
302+
303+
req.on('error', err => {
304+
assert.ifError(err);
305+
});
306+
307+
308+
req.once('drain', () => {
309+
req.end();
310+
});
311+
312+
req.write(objData, err => {
313+
assert.ifError(err);
314+
req.end();
315+
});
316+
});
317+
}
318+
}
319+
});

0 commit comments

Comments
 (0)