Skip to content

Commit 180aebd

Browse files
committed
Add extraHeadersToIgnore and extraHeadersToInclude options
Fixes #37 for OpenSearch Serverless among others
1 parent a413aad commit 180aebd

File tree

3 files changed

+83
-2
lines changed

3 files changed

+83
-2
lines changed

README.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,34 @@ request(aws4.sign({
9494
...
9595
*/
9696

97+
// you can also specify extra headers to ignore during signing
98+
request(aws4.sign({
99+
host: '07tjusf2h91cunochc.us-east-1.aoss.amazonaws.com',
100+
method: 'PUT',
101+
path: '/my-index',
102+
body: '{"mappings":{}}',
103+
headers: {
104+
'Content-Type': 'application/json',
105+
'X-Amz-Content-Sha256': 'UNSIGNED-PAYLOAD'
106+
},
107+
extraHeadersToIgnore: {
108+
'content-length': true
109+
}
110+
}))
111+
112+
// and headers to include that would normally be ignored
113+
request(aws4.sign({
114+
service: 'mycustomservice',
115+
path: '/whatever',
116+
headers: {
117+
'Range': 'bytes=200-1000, 2000-6576, 19000-'
118+
},
119+
extraHeadersToInclude: {
120+
'range': true
121+
}
122+
}))
123+
124+
97125
// The raw RequestSigner can be used to generate CodeCommit Git passwords
98126
var signer = new aws4.RequestSigner({
99127
service: 'codecommit',
@@ -128,6 +156,8 @@ populated if they don't already exist:
128156
- `service` (will try to be calculated from `hostname` or `host` if not given)
129157
- `region` (will try to be calculated from `hostname` or `host` or use `'us-east-1'` if not given)
130158
- `signQuery` (to sign the query instead of adding an `Authorization` header, defaults to false)
159+
- `extraHeadersToIgnore` (an object with lowercase header keys to ignore when signing, eg `{ 'content-length': true }`)
160+
- `extraHeadersToInclude` (an object with lowercase header keys to include when signing, overriding any ignores)
131161
- `headers['Host']` (will use `hostname` or `host` or be calculated if not given)
132162
- `headers['Content-Type']` (will use `'application/x-www-form-urlencoded; charset=utf-8'`
133163
if not given and there is a `body`)

aws4.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ function RequestSigner(request, credentials) {
7272
request.hostname = headers.Host || headers.host
7373

7474
this.isCodeCommitGit = this.service === 'codecommit' && request.method === 'GIT'
75+
76+
this.extraHeadersToIgnore = request.extraHeadersToIgnore || Object.create(null)
77+
this.extraHeadersToInclude = request.extraHeadersToInclude || Object.create(null)
7578
}
7679

7780
RequestSigner.prototype.matchHost = function(host) {
@@ -81,7 +84,7 @@ RequestSigner.prototype.matchHost = function(host) {
8184
// ES's hostParts are sometimes the other way round, if the value that is expected
8285
// to be region equals ‘es’ switch them back
8386
// e.g. search-cluster-name-aaaa00aaaa0aaa0aaaaaaa0aaa.us-east-1.es.amazonaws.com
84-
if (hostParts[1] === 'es')
87+
if (hostParts[1] === 'es' || hostParts[1] === 'aoss')
8588
hostParts = hostParts.reverse()
8689

8790
if (hostParts[1] == 's3') {
@@ -305,9 +308,14 @@ RequestSigner.prototype.canonicalHeaders = function() {
305308
}
306309

307310
RequestSigner.prototype.signedHeaders = function() {
311+
var extraHeadersToInclude = this.extraHeadersToInclude,
312+
extraHeadersToIgnore = this.extraHeadersToIgnore
308313
return Object.keys(this.request.headers)
309314
.map(function(key) { return key.toLowerCase() })
310-
.filter(function(key) { return HEADERS_TO_IGNORE[key] == null })
315+
.filter(function(key) {
316+
return extraHeadersToInclude[key] ||
317+
(HEADERS_TO_IGNORE[key] == null && !extraHeadersToIgnore[key])
318+
})
311319
.sort()
312320
.join(';')
313321
}

test/fast.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,49 @@ describe('aws4', function() {
367367
})
368368
})
369369

370+
describe('#sign() with extraHeadersToIgnore', function() {
371+
it('should generate signature correctly', function() {
372+
var opts = aws4.sign({
373+
host: '07tjusf2h91cunochc.us-east-1.aoss.amazonaws.com',
374+
method: 'PUT',
375+
path: '/my-index',
376+
body: '{"mappings":{}}',
377+
headers: {
378+
Date: date,
379+
'Content-Type': 'application/json',
380+
'X-Amz-Content-Sha256': 'UNSIGNED-PAYLOAD',
381+
},
382+
extraHeadersToIgnore: {
383+
'content-length': true
384+
},
385+
})
386+
opts.headers.Authorization.should.equal(
387+
'AWS4-HMAC-SHA256 Credential=ABCDEF/20121226/us-east-1/aoss/aws4_request, ' +
388+
'SignedHeaders=content-type;date;host;x-amz-content-sha256;x-amz-date, ' +
389+
'Signature=ade8635c05bfa4961bc28be0b0a0fbfd3d64e79feb1862f822ee6a4517417bcd')
390+
})
391+
})
392+
393+
describe('#sign() with extraHeadersToInclude', function() {
394+
it('should generate signature correctly', function() {
395+
var opts = aws4.sign({
396+
service: 'someservice',
397+
path: '/whatever',
398+
headers: {
399+
Date: date,
400+
'Range': 'bytes=200-1000, 2000-6576, 19000-',
401+
},
402+
extraHeadersToInclude: {
403+
'range': true
404+
},
405+
})
406+
opts.headers.Authorization.should.equal(
407+
'AWS4-HMAC-SHA256 Credential=ABCDEF/20121226/us-east-1/someservice/aws4_request, ' +
408+
'SignedHeaders=date;host;range;x-amz-date, ' +
409+
'Signature=8f3eba7a5743091daae62d00ce1c911c018d48f72dbdf180b15abe701718317a')
410+
})
411+
})
412+
370413
describe('#signature() with CodeCommit Git access', function() {
371414
it('should generate signature correctly', function() {
372415
var signer = new RequestSigner({

0 commit comments

Comments
 (0)