Skip to content
Open
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
88 changes: 79 additions & 9 deletions packages/dd-trace/src/plugins/util/web.js
Original file line number Diff line number Diff line change
Expand Up @@ -333,15 +333,31 @@ const web = {
// GET / POST / etc. case. Node's http module passes `req.method`
// through unchanged, so all standard methods are uppercase; the
// `toLowerCase` fallback covers any non-standard caller.
let headersModified = false
const hasStatusMessage = (statusMessage && typeof statusMessage === 'string')
if (req.method === 'OPTIONS' || req.method.toLowerCase() === 'options') {
headers = typeof statusMessage === 'string' ? headers : statusMessage
headers = { ...res.getHeaders(), ...headers }

if (isOriginAllowed(req, headers)) {
addAllowHeaders(req, res, headers)
headers = hasStatusMessage ? headers : statusMessage
const headersAreArray = Array.isArray(headers)
const headersLookup = normalizeHeaderLookup(headers)
const mergedHeaders = { ...res.getHeaders(), ...headersLookup }

if (isOriginAllowed(req, mergedHeaders)) {
const allowedHeaders = computeAllowedHeaders(req, mergedHeaders)
if (allowedHeaders) {
headers = headersAreArray
? setFlatHeader(headers, 'access-control-allow-headers', allowedHeaders)
: setObjectHeader(headers, 'access-control-allow-headers', allowedHeaders)
headersModified = true
}
}
}

if (headersModified) {
if (hasStatusMessage) {
return writeHead.call(this, statusCode, statusMessage, headers)
}
return writeHead.call(this, statusCode, headers)
Comment thread
pabloerhard marked this conversation as resolved.
}
return writeHead.apply(this, arguments)
}
},
Expand Down Expand Up @@ -372,7 +388,7 @@ function normalizeHeadersCarrier (headers) {
return carrier
}

function addAllowHeaders (req, res, headers) {
function computeAllowedHeaders (req, headers) {
const allowHeaders = splitHeader(headers['access-control-allow-headers'])
const requestHeaders = splitHeader(req.headers['access-control-request-headers'])
const contextHeaders = [
Expand All @@ -393,9 +409,7 @@ function addAllowHeaders (req, res, headers) {
}
}

if (allowHeaders.length > 0) {
res.setHeader('access-control-allow-headers', uniq(allowHeaders).join(','))
}
return uniq(allowHeaders).join(',')
}

function isOriginAllowed (req, headers) {
Expand All @@ -409,6 +423,62 @@ function splitHeader (str) {
return typeof str === 'string' ? str.split(',').map((header) => header.trim()) : []
}

function normalizeHeaderLookup (headers) {
const result = {}

if (Array.isArray(headers)) {
for (let i = 0; i < headers.length; i += 2) {
result[headers[i].toLowerCase()] = headers[i + 1]
}
} else if (headers) {
for (const key of Object.keys(headers)) {
result[key.toLowerCase()] = headers[key]
}
}

return result
}

function setFlatHeader (headers, name, value) {
const result = [...headers]
let headerFound = false

for (let i = 0; i < result.length; i += 2) {
if (result[i].toLowerCase() === name) {
result[i + 1] = value
headerFound = true
}
}

if (!headerFound) {
result.push(name, value)
}

return result
}

function setObjectHeader (headers, name, value) {
const result = {}
let headerFound = false

if (headers) {
for (const key of Object.keys(headers)) {
if (key.toLowerCase() === name) {
result[key] = value
headerFound = true
} else {
result[key] = headers[key]
}
}
}

if (!headerFound) {
result[name] = value
}

return result
}

function addRequestTags (context, spanType) {
const { req, span, inferredProxySpan, config } = context
const spanContext = span.context()
Expand Down
Loading
Loading