Skip to content

Commit

Permalink
Merge branch 'master' into automatic_userid_blocking
Browse files Browse the repository at this point in the history
  • Loading branch information
simon-id authored Jan 18, 2025
2 parents 60789f4 + 4ef12fc commit 1cb83fb
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 165 deletions.
38 changes: 5 additions & 33 deletions packages/datadog-plugin-http/src/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ class HttpClientPlugin extends ClientPlugin {
}

if (this.shouldInjectTraceHeaders(options, uri)) {
// Clone the headers object in case an upstream lib has a reference to the original headers
// Implemented due to aws-sdk issue where request signing is broken if we mutate the headers
// Explained further in:
// https://github.com/open-telemetry/opentelemetry-js-contrib/issues/1609#issuecomment-1826167348
options.headers = Object.assign({}, options.headers)
this.tracer.inject(span, HTTP_HEADERS, options.headers)
}

Expand All @@ -72,10 +77,6 @@ class HttpClientPlugin extends ClientPlugin {
}

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

if (!this.config.propagationFilter(uri)) {
return false
}
Expand Down Expand Up @@ -212,31 +213,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 +224,4 @@ function extractSessionDetails (options) {
return { host, port }
}

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

module.exports = HttpClientPlugin
141 changes: 12 additions & 129 deletions packages/datadog-plugin-http/test/client.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -446,97 +446,24 @@ 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 ...'
}
})
it('should inject tracing header into request without mutating the header', done => {
// ensures that the tracer clones request headers instead of mutating.
// Fixes aws-sdk InvalidSignatureException, more info:
// https://github.com/open-telemetry/opentelemetry-js-contrib/issues/1609#issuecomment-1826167348

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()
const originalHeaders = {
Authorization: 'AWS4-HMAC-SHA256 ...'
}

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()
expect(req.get('x-datadog-trace-id')).to.be.a('string')
expect(req.get('x-datadog-parent-id')).to.be.a('string')

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
expect(originalHeaders['x-datadog-trace-id']).to.be.undefined
expect(originalHeaders['x-datadog-parent-id']).to.be.undefined

res.status(200).send()

Expand All @@ -549,7 +476,7 @@ describe('Plugin', () => {
appListener = server(app, port => {
const req = http.request({
port,
path: '/?X-Amz-Signature=abc123'
headers: originalHeaders
})

req.end()
Expand Down Expand Up @@ -1093,50 +1020,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
6 changes: 3 additions & 3 deletions packages/dd-trace/src/llmobs/writers/spans/agentProxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ const LLMObsBaseSpanWriter = require('./base')
class LLMObsAgentProxySpanWriter extends LLMObsBaseSpanWriter {
constructor (config) {
super({
intake: config.hostname || 'localhost',
protocol: 'http:',
intake: config.url?.hostname || config.hostname || 'localhost',
protocol: config.url?.protocol || 'http:',
endpoint: EVP_PROXY_AGENT_ENDPOINT,
port: config.port
port: config.url?.port || config.port
})

this._headers[EVP_SUBDOMAIN_HEADER_NAME] = EVP_SUBDOMAIN_HEADER_VALUE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,12 @@ describe('LLMObsAgentProxySpanWriter', () => {

expect(writer._url.href).to.equal('http://localhost:8126/evp_proxy/v2/api/v2/llmobs')
})

it('uses the url property if provided on the config', () => {
writer = new LLMObsAgentProxySpanWriter({
url: new URL('http://test-agent:12345')
})

expect(writer._url.href).to.equal('http://test-agent:12345/evp_proxy/v2/api/v2/llmobs')
})
})

0 comments on commit 1cb83fb

Please sign in to comment.