Skip to content

Commit 04a6184

Browse files
authored
Merge branch 'master' into template-injection-handlebars
2 parents 0408305 + 0a411ee commit 04a6184

21 files changed

Lines changed: 1010 additions & 211 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ typings/
106106

107107
# End of https://www.gitignore.io/api/node,macos,visualstudiocode
108108

109+
.github/notes
109110
.next
110111
package-lock.json
111112
out

docs/test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,9 @@ tracer.use('http', {
324324
tracer.use('http', {
325325
client: httpClientOptions
326326
});
327+
tracer.use('http', {
328+
enablePropagationWithAmazonHeaders: true
329+
});
327330
tracer.use('http2');
328331
tracer.use('http2', {
329332
server: http2ServerOptions

index.d.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,6 +1043,14 @@ declare namespace tracer {
10431043
* @default code => code < 500
10441044
*/
10451045
validateStatus?: (code: number) => boolean;
1046+
1047+
/**
1048+
* Enable injection of tracing headers into requests signed with AWS IAM headers.
1049+
* Disable this if you get AWS signature errors (HTTP 403).
1050+
*
1051+
* @default false
1052+
*/
1053+
enablePropagationWithAmazonHeaders?: boolean;
10461054
}
10471055

10481056
/** @hidden */

packages/datadog-plugin-aws-sdk/src/services/eventbridge.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const BaseAwsSdkPlugin = require('../base')
44

55
class EventBridge extends BaseAwsSdkPlugin {
66
static get id () { return 'eventbridge' }
7+
static get isPayloadReporter () { return true }
78

89
generateTags (params, operation, response) {
910
if (!params || !params.source) return {}

packages/datadog-plugin-aws-sdk/src/services/kinesis.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const { storage } = require('../../../datadog-core')
1010
class Kinesis extends BaseAwsSdkPlugin {
1111
static get id () { return 'kinesis' }
1212
static get peerServicePrecursors () { return ['streamname'] }
13+
static get isPayloadReporter () { return true }
1314

1415
constructor (...args) {
1516
super(...args)

packages/datadog-plugin-aws-sdk/src/services/s3.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const BaseAwsSdkPlugin = require('../base')
55
class S3 extends BaseAwsSdkPlugin {
66
static get id () { return 's3' }
77
static get peerServicePrecursors () { return ['bucketname'] }
8+
static get isPayloadReporter () { return true }
89

910
generateTags (params, operation, response) {
1011
const tags = {}

packages/datadog-plugin-aws-sdk/src/services/sqs.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const { DsmPathwayCodec } = require('../../../dd-trace/src/datastreams/pathway')
99
class Sqs extends BaseAwsSdkPlugin {
1010
static get id () { return 'sqs' }
1111
static get peerServicePrecursors () { return ['queuename'] }
12+
static get isPayloadReporter () { return true }
1213

1314
constructor (...args) {
1415
super(...args)

packages/datadog-plugin-aws-sdk/test/aws-sdk.spec.js

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -114,28 +114,6 @@ describe('Plugin', () => {
114114
s3.listBuckets({}, e => e && done(e))
115115
})
116116

117-
// different versions of aws-sdk use different casings and different AWS headers
118-
it('should include tracing headers and not cause a 403 error', (done) => {
119-
const HttpClientPlugin = require('../../datadog-plugin-http/src/client.js')
120-
const spy = sinon.spy(HttpClientPlugin.prototype, 'bindStart')
121-
agent.use(traces => {
122-
const headers = new Set(
123-
Object.keys(spy.firstCall.firstArg.args.options.headers)
124-
.map(x => x.toLowerCase())
125-
)
126-
spy.restore()
127-
128-
expect(headers).to.include('authorization')
129-
expect(headers).to.include('x-amz-date')
130-
expect(headers).to.include('x-datadog-trace-id')
131-
expect(headers).to.include('x-datadog-parent-id')
132-
expect(headers).to.include('x-datadog-sampling-priority')
133-
expect(headers).to.include('x-datadog-tags')
134-
}).then(done, done)
135-
136-
s3.listBuckets({}, e => e && done(e))
137-
})
138-
139117
it('should mark error responses', (done) => {
140118
let error
141119

packages/datadog-plugin-fetch/test/index.spec.js

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,102 @@ describe('Plugin', () => {
215215
})
216216
})
217217

218+
it('should skip injecting if the Authorization header contains an AWS signature', done => {
219+
const app = express()
220+
221+
app.get('/', (req, res) => {
222+
try {
223+
expect(req.get('x-datadog-trace-id')).to.be.undefined
224+
expect(req.get('x-datadog-parent-id')).to.be.undefined
225+
226+
res.status(200).send()
227+
228+
done()
229+
} catch (e) {
230+
done(e)
231+
}
232+
})
233+
234+
appListener = server(app, port => {
235+
fetch(`http://localhost:${port}/`, {
236+
headers: {
237+
Authorization: 'AWS4-HMAC-SHA256 ...'
238+
}
239+
})
240+
})
241+
})
242+
243+
it('should skip injecting if one of the Authorization headers contains an AWS signature', done => {
244+
const app = express()
245+
246+
app.get('/', (req, res) => {
247+
try {
248+
expect(req.get('x-datadog-trace-id')).to.be.undefined
249+
expect(req.get('x-datadog-parent-id')).to.be.undefined
250+
251+
res.status(200).send()
252+
253+
done()
254+
} catch (e) {
255+
done(e)
256+
}
257+
})
258+
259+
appListener = server(app, port => {
260+
fetch(`http://localhost:${port}/`, {
261+
headers: {
262+
Authorization: ['AWS4-HMAC-SHA256 ...']
263+
}
264+
})
265+
})
266+
})
267+
268+
it('should skip injecting if the X-Amz-Signature header is set', done => {
269+
const app = express()
270+
271+
app.get('/', (req, res) => {
272+
try {
273+
expect(req.get('x-datadog-trace-id')).to.be.undefined
274+
expect(req.get('x-datadog-parent-id')).to.be.undefined
275+
276+
res.status(200).send()
277+
278+
done()
279+
} catch (e) {
280+
done(e)
281+
}
282+
})
283+
284+
appListener = server(app, port => {
285+
fetch(`http://localhost:${port}/`, {
286+
headers: {
287+
'X-Amz-Signature': 'abc123'
288+
}
289+
})
290+
})
291+
})
292+
293+
it('should skip injecting if the X-Amz-Signature query param is set', done => {
294+
const app = express()
295+
296+
app.get('/', (req, res) => {
297+
try {
298+
expect(req.get('x-datadog-trace-id')).to.be.undefined
299+
expect(req.get('x-datadog-parent-id')).to.be.undefined
300+
301+
res.status(200).send()
302+
303+
done()
304+
} catch (e) {
305+
done(e)
306+
}
307+
})
308+
309+
appListener = server(app, port => {
310+
fetch(`http://localhost:${port}/?X-Amz-Signature=abc123`)
311+
})
312+
})
313+
218314
it('should handle connection errors', done => {
219315
let error
220316

packages/datadog-plugin-http/src/client.js

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class HttpClientPlugin extends ClientPlugin {
5858
span._spanContext._trace.record = false
5959
}
6060

61-
if (this.config.propagationFilter(uri)) {
61+
if (this.shouldInjectTraceHeaders(options, uri)) {
6262
this.tracer.inject(span, HTTP_HEADERS, options.headers)
6363
}
6464

@@ -71,6 +71,18 @@ class HttpClientPlugin extends ClientPlugin {
7171
return message.currentStore
7272
}
7373

74+
shouldInjectTraceHeaders (options, uri) {
75+
if (hasAmazonSignature(options) && !this.config.enablePropagationWithAmazonHeaders) {
76+
return false
77+
}
78+
79+
if (!this.config.propagationFilter(uri)) {
80+
return false
81+
}
82+
83+
return true
84+
}
85+
7486
bindAsyncStart ({ parentStore }) {
7587
return parentStore
7688
}
@@ -200,6 +212,31 @@ function getHooks (config) {
200212
return { request }
201213
}
202214

215+
function hasAmazonSignature (options) {
216+
if (!options) {
217+
return false
218+
}
219+
220+
if (options.headers) {
221+
const headers = Object.keys(options.headers)
222+
.reduce((prev, next) => Object.assign(prev, {
223+
[next.toLowerCase()]: options.headers[next]
224+
}), {})
225+
226+
if (headers['x-amz-signature']) {
227+
return true
228+
}
229+
230+
if ([].concat(headers.authorization).some(startsWith('AWS4-HMAC-SHA256'))) {
231+
return true
232+
}
233+
}
234+
235+
const search = options.search || options.path
236+
237+
return search && search.toLowerCase().indexOf('x-amz-signature=') !== -1
238+
}
239+
203240
function extractSessionDetails (options) {
204241
if (typeof options === 'string') {
205242
return new URL(options).host
@@ -211,4 +248,8 @@ function extractSessionDetails (options) {
211248
return { host, port }
212249
}
213250

251+
function startsWith (searchString) {
252+
return value => String(value).startsWith(searchString)
253+
}
254+
214255
module.exports = HttpClientPlugin

0 commit comments

Comments
 (0)