Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

always enable tracing header injection for AWS requests #4717

Merged
merged 2 commits into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions docs/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -320,9 +320,6 @@ tracer.use('http', {
tracer.use('http', {
client: httpClientOptions
});
tracer.use('http', {
enablePropagationWithAmazonHeaders: true
});
tracer.use('http2');
tracer.use('http2', {
server: http2ServerOptions
Expand Down
8 changes: 0 additions & 8 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1030,14 +1030,6 @@ declare namespace tracer {
* @default code => code < 500
*/
validateStatus?: (code: number) => boolean;

/**
* Enable injection of tracing headers into requests signed with AWS IAM headers.
* Disable this if you get AWS signature errors (HTTP 403).
*
* @default false
*/
enablePropagationWithAmazonHeaders?: boolean;
}

/** @hidden */
Expand Down
22 changes: 22 additions & 0 deletions packages/datadog-plugin-aws-sdk/test/aws-sdk.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,28 @@ describe('Plugin', () => {
s3.listBuckets({}, e => e && done(e))
})

// different versions of aws-sdk use different casings and different AWS headers
it('should include tracing headers and not cause a 403 error', (done) => {
const HttpClientPlugin = require('../../datadog-plugin-http/src/client.js')
const spy = sinon.spy(HttpClientPlugin.prototype, 'bindStart')
agent.use(traces => {
const headers = new Set(
Object.keys(spy.firstCall.firstArg.args.options.headers)
.map(x => x.toLowerCase())
)
spy.restore()

expect(headers).to.include('authorization')
expect(headers).to.include('x-amz-date')
expect(headers).to.include('x-datadog-trace-id')
expect(headers).to.include('x-datadog-parent-id')
expect(headers).to.include('x-datadog-sampling-priority')
expect(headers).to.include('x-datadog-tags')
}).then(done, done)

s3.listBuckets({}, e => e && done(e))
})

it('should mark error responses', (done) => {
let error

Expand Down
96 changes: 0 additions & 96 deletions packages/datadog-plugin-fetch/test/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -215,102 +215,6 @@ describe('Plugin', () => {
})
})

it('should skip injecting if the Authorization header contains an AWS signature', done => {
const app = express()

app.get('/', (req, res) => {
try {
expect(req.get('x-datadog-trace-id')).to.be.undefined
expect(req.get('x-datadog-parent-id')).to.be.undefined

res.status(200).send()

done()
} catch (e) {
done(e)
}
})

appListener = server(app, port => {
fetch(`http://localhost:${port}/`, {
headers: {
Authorization: 'AWS4-HMAC-SHA256 ...'
}
})
})
})

it('should skip injecting if one of the Authorization headers contains an AWS signature', done => {
const app = express()

app.get('/', (req, res) => {
try {
expect(req.get('x-datadog-trace-id')).to.be.undefined
expect(req.get('x-datadog-parent-id')).to.be.undefined

res.status(200).send()

done()
} catch (e) {
done(e)
}
})

appListener = server(app, port => {
fetch(`http://localhost:${port}/`, {
headers: {
Authorization: ['AWS4-HMAC-SHA256 ...']
}
})
})
})

it('should skip injecting if the X-Amz-Signature header is set', done => {
const app = express()

app.get('/', (req, res) => {
try {
expect(req.get('x-datadog-trace-id')).to.be.undefined
expect(req.get('x-datadog-parent-id')).to.be.undefined

res.status(200).send()

done()
} catch (e) {
done(e)
}
})

appListener = server(app, port => {
fetch(`http://localhost:${port}/`, {
headers: {
'X-Amz-Signature': 'abc123'
}
})
})
})

it('should skip injecting if the X-Amz-Signature query param is set', done => {
const app = express()

app.get('/', (req, res) => {
try {
expect(req.get('x-datadog-trace-id')).to.be.undefined
expect(req.get('x-datadog-parent-id')).to.be.undefined

res.status(200).send()

done()
} catch (e) {
done(e)
}
})

appListener = server(app, port => {
fetch(`http://localhost:${port}/?X-Amz-Signature=abc123`)
})
})

it('should handle connection errors', done => {
let error

Expand Down
43 changes: 1 addition & 42 deletions packages/datadog-plugin-http/src/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class HttpClientPlugin extends ClientPlugin {
span._spanContext._trace.record = false
}

if (this.shouldInjectTraceHeaders(options, uri)) {
if (this.config.propagationFilter(uri)) {
this.tracer.inject(span, HTTP_HEADERS, options.headers)
}

Expand All @@ -71,18 +71,6 @@ class HttpClientPlugin extends ClientPlugin {
return message.currentStore
}

shouldInjectTraceHeaders (options, uri) {
if (hasAmazonSignature(options) && !this.config.enablePropagationWithAmazonHeaders) {
return false
}

if (!this.config.propagationFilter(uri)) {
return false
}

return true
}

bindAsyncStart ({ parentStore }) {
return parentStore
}
Expand Down Expand Up @@ -212,31 +200,6 @@ function getHooks (config) {
return { request }
}

function hasAmazonSignature (options) {
if (!options) {
return false
}

if (options.headers) {
const headers = Object.keys(options.headers)
.reduce((prev, next) => Object.assign(prev, {
[next.toLowerCase()]: options.headers[next]
}), {})

if (headers['x-amz-signature']) {
return true
}

if ([].concat(headers.authorization).some(startsWith('AWS4-HMAC-SHA256'))) {
return true
}
}

const search = options.search || options.path

return search && search.toLowerCase().indexOf('x-amz-signature=') !== -1
}

function extractSessionDetails (options) {
if (typeof options === 'string') {
return new URL(options).host
Expand All @@ -248,8 +211,4 @@ function extractSessionDetails (options) {
return { host, port }
}

function startsWith (searchString) {
return value => String(value).startsWith(searchString)
}

module.exports = HttpClientPlugin
154 changes: 0 additions & 154 deletions packages/datadog-plugin-http/test/client.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -446,116 +446,6 @@ describe('Plugin', () => {
})
})

it('should skip injecting if the Authorization header contains an AWS signature', done => {
const app = express()

app.get('/', (req, res) => {
try {
expect(req.get('x-datadog-trace-id')).to.be.undefined
expect(req.get('x-datadog-parent-id')).to.be.undefined

res.status(200).send()

done()
} catch (e) {
done(e)
}
})

appListener = server(app, port => {
const req = http.request({
port,
headers: {
Authorization: 'AWS4-HMAC-SHA256 ...'
}
})

req.end()
})
})

it('should skip injecting if one of the Authorization headers contains an AWS signature', done => {
const app = express()

app.get('/', (req, res) => {
try {
expect(req.get('x-datadog-trace-id')).to.be.undefined
expect(req.get('x-datadog-parent-id')).to.be.undefined

res.status(200).send()

done()
} catch (e) {
done(e)
}
})

appListener = server(app, port => {
const req = http.request({
port,
headers: {
Authorization: ['AWS4-HMAC-SHA256 ...']
}
})

req.end()
})
})

it('should skip injecting if the X-Amz-Signature header is set', done => {
const app = express()

app.get('/', (req, res) => {
try {
expect(req.get('x-datadog-trace-id')).to.be.undefined
expect(req.get('x-datadog-parent-id')).to.be.undefined

res.status(200).send()

done()
} catch (e) {
done(e)
}
})

appListener = server(app, port => {
const req = http.request({
port,
headers: {
'X-Amz-Signature': 'abc123'
}
})

req.end()
})
})

it('should skip injecting if the X-Amz-Signature query param is set', done => {
const app = express()

app.get('/', (req, res) => {
try {
expect(req.get('x-datadog-trace-id')).to.be.undefined
expect(req.get('x-datadog-parent-id')).to.be.undefined

res.status(200).send()

done()
} catch (e) {
done(e)
}
})

appListener = server(app, port => {
const req = http.request({
port,
path: '/?X-Amz-Signature=abc123'
})

req.end()
})
})

it('should run the callback in the parent context', done => {
const app = express()

Expand Down Expand Up @@ -1093,50 +983,6 @@ describe('Plugin', () => {
})
})

describe('with config enablePropagationWithAmazonHeaders enabled', () => {
let config

beforeEach(() => {
config = {
enablePropagationWithAmazonHeaders: true
}

return agent.load('http', config)
.then(() => {
http = require(pluginToBeLoaded)
express = require('express')
})
})

it('should inject tracing header into AWS signed request', done => {
const app = express()

app.get('/', (req, res) => {
try {
expect(req.get('x-datadog-trace-id')).to.be.a('string')
expect(req.get('x-datadog-parent-id')).to.be.a('string')

res.status(200).send()

done()
} catch (e) {
done(e)
}
})

appListener = server(app, port => {
const req = http.request({
port,
headers: {
Authorization: 'AWS4-HMAC-SHA256 ...'
}
})

req.end()
})
})
})

describe('with validateStatus configuration', () => {
let config

Expand Down
Loading
Loading