Skip to content

Commit

Permalink
Add extraHeadersToIgnore and extraHeadersToInclude options
Browse files Browse the repository at this point in the history
Fixes #37 for OpenSearch Serverless among others
  • Loading branch information
mhart committed Jan 7, 2023
1 parent a413aad commit 180aebd
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 2 deletions.
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,34 @@ request(aws4.sign({
...
*/

// you can also specify extra headers to ignore during signing
request(aws4.sign({
host: '07tjusf2h91cunochc.us-east-1.aoss.amazonaws.com',
method: 'PUT',
path: '/my-index',
body: '{"mappings":{}}',
headers: {
'Content-Type': 'application/json',
'X-Amz-Content-Sha256': 'UNSIGNED-PAYLOAD'
},
extraHeadersToIgnore: {
'content-length': true
}
}))

// and headers to include that would normally be ignored
request(aws4.sign({
service: 'mycustomservice',
path: '/whatever',
headers: {
'Range': 'bytes=200-1000, 2000-6576, 19000-'
},
extraHeadersToInclude: {
'range': true
}
}))


// The raw RequestSigner can be used to generate CodeCommit Git passwords
var signer = new aws4.RequestSigner({
service: 'codecommit',
Expand Down Expand Up @@ -128,6 +156,8 @@ populated if they don't already exist:
- `service` (will try to be calculated from `hostname` or `host` if not given)
- `region` (will try to be calculated from `hostname` or `host` or use `'us-east-1'` if not given)
- `signQuery` (to sign the query instead of adding an `Authorization` header, defaults to false)
- `extraHeadersToIgnore` (an object with lowercase header keys to ignore when signing, eg `{ 'content-length': true }`)
- `extraHeadersToInclude` (an object with lowercase header keys to include when signing, overriding any ignores)
- `headers['Host']` (will use `hostname` or `host` or be calculated if not given)
- `headers['Content-Type']` (will use `'application/x-www-form-urlencoded; charset=utf-8'`
if not given and there is a `body`)
Expand Down
12 changes: 10 additions & 2 deletions aws4.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ function RequestSigner(request, credentials) {
request.hostname = headers.Host || headers.host

this.isCodeCommitGit = this.service === 'codecommit' && request.method === 'GIT'

this.extraHeadersToIgnore = request.extraHeadersToIgnore || Object.create(null)
this.extraHeadersToInclude = request.extraHeadersToInclude || Object.create(null)
}

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

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

RequestSigner.prototype.signedHeaders = function() {
var extraHeadersToInclude = this.extraHeadersToInclude,
extraHeadersToIgnore = this.extraHeadersToIgnore
return Object.keys(this.request.headers)
.map(function(key) { return key.toLowerCase() })
.filter(function(key) { return HEADERS_TO_IGNORE[key] == null })
.filter(function(key) {
return extraHeadersToInclude[key] ||
(HEADERS_TO_IGNORE[key] == null && !extraHeadersToIgnore[key])
})
.sort()
.join(';')
}
Expand Down
43 changes: 43 additions & 0 deletions test/fast.js
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,49 @@ describe('aws4', function() {
})
})

describe('#sign() with extraHeadersToIgnore', function() {
it('should generate signature correctly', function() {
var opts = aws4.sign({
host: '07tjusf2h91cunochc.us-east-1.aoss.amazonaws.com',
method: 'PUT',
path: '/my-index',
body: '{"mappings":{}}',
headers: {
Date: date,
'Content-Type': 'application/json',
'X-Amz-Content-Sha256': 'UNSIGNED-PAYLOAD',
},
extraHeadersToIgnore: {
'content-length': true
},
})
opts.headers.Authorization.should.equal(
'AWS4-HMAC-SHA256 Credential=ABCDEF/20121226/us-east-1/aoss/aws4_request, ' +
'SignedHeaders=content-type;date;host;x-amz-content-sha256;x-amz-date, ' +
'Signature=ade8635c05bfa4961bc28be0b0a0fbfd3d64e79feb1862f822ee6a4517417bcd')
})
})

describe('#sign() with extraHeadersToInclude', function() {
it('should generate signature correctly', function() {
var opts = aws4.sign({
service: 'someservice',
path: '/whatever',
headers: {
Date: date,
'Range': 'bytes=200-1000, 2000-6576, 19000-',
},
extraHeadersToInclude: {
'range': true
},
})
opts.headers.Authorization.should.equal(
'AWS4-HMAC-SHA256 Credential=ABCDEF/20121226/us-east-1/someservice/aws4_request, ' +
'SignedHeaders=date;host;range;x-amz-date, ' +
'Signature=8f3eba7a5743091daae62d00ce1c911c018d48f72dbdf180b15abe701718317a')
})
})

describe('#signature() with CodeCommit Git access', function() {
it('should generate signature correctly', function() {
var signer = new RequestSigner({
Expand Down

0 comments on commit 180aebd

Please sign in to comment.