UNPKG

newrelic

Version:
166 lines (144 loc) 5.04 kB
/* * Copyright 2020 New Relic Corporation. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ 'use strict' const DESTS = require('./config/attribute-filter').DESTINATIONS const COLLECTED_REQUEST_HEADERS = [ 'accept', 'content-length', 'content-type', 'referer', 'user-agent', 'host' ] const HEADER_ATTR_NAMES = { accept: 'accept', 'accept-charset': 'acceptCharset', 'accept-encoding': 'acceptEncoding', 'access-control-allow-headers': 'accessControlAllowHeaders', 'access-control-allow-methods': 'accessControlAllowMethods', 'access-control-allow-origin': 'accessControlAllowOrigin', age: 'age', allow: 'allow', authorization: 'authorization', 'cache-control': 'cacheControl', connection: 'connection', cookie: 'cookie', 'content-encoding': 'contentEncoding', 'content-length': 'contentLength', 'content-type': 'contentType', date: 'date', etag: 'eTag', expect: 'expect', expires: 'expires', forwarded: 'forwarded', host: 'host', 'if-match': 'ifMatch', 'if-modified-since': 'ifModifiedSince', 'last-modified': 'lastModified', location: 'location', newrelic: 'newrelic', origin: 'origin', 'proxy-authorization': 'proxyAuthorization', referer: 'referer', refresh: 'refresh', server: 'server', 'set-cookie': 'setCookie', 'transfer-encoding': 'transferEncoding', 'user-agent': 'userAgent', upgrade: 'upgrade', vary: 'vary', 'x-correlation-id': 'xCorrelationId', 'x-csrf-token': 'xCsrfToken', 'x-forwarded-for': 'xForwardedFor', 'x-http-method-override': 'xHttpMethodOverride', 'x-newrelic-app-data': 'xNewrelicAppData', 'x-newrelic-id': 'xNewrelicId', 'x-newrelic-synthetics': 'xNewrelicSynthetics', 'x-newrelic-synthetics-info': 'xNewrelicSyntheticsInfo', 'x-newrelic-transaction': 'xNewrelicTransaction', 'x-powered-by': 'xPoweredBy', 'x-queue-start': 'xQueueStart', 'x-request-id': 'xRequestId', 'x-request-start': 'xRequestStart', 'x-requested-with': 'xRequestedWith' } const REQUEST_HEADER_PREFIX = 'request.headers.' const RESPONSE_HEADER_PREFIX = 'response.headers.' const REQUEST_HEADER_NAMES = Object.create(null) const RESPONSE_HEADER_NAMES = Object.create(null) _setHeaderAttrNames(REQUEST_HEADER_NAMES, REQUEST_HEADER_PREFIX) _setHeaderAttrNames(RESPONSE_HEADER_NAMES, RESPONSE_HEADER_PREFIX) function _setHeaderAttrNames(dest, prefix) { Object.keys(HEADER_ATTR_NAMES).forEach(function forEachHeader(h) { dest[h] = prefix + HEADER_ATTR_NAMES[h] }) } function _headerToCamelCase(header) { if (header.length === 0) { return '' } if (header.length === 1) { return header.toLowerCase() } const newHeader = header.charAt(0).toLowerCase() + header.slice(1) // Converts headers in the form 'header-name' to be in the form 'headerName' return newHeader.split(/[\W_]/).map((ele, i) => { if (i === 0) return ele return ele.slice(0, 1).toUpperCase() + ele.slice(1) }).join('') } function _collectHeaders(headers, nameMap, prefix, transaction) { if (!headers) { return } if (!transaction.agent.config.allow_all_headers) { headers = Object.keys(headers).reduce((collection, key) => { collection[key.toLowerCase()] = headers[key] return collection }, {}) } const headerKeys = !transaction.agent.config.allow_all_headers ? COLLECTED_REQUEST_HEADERS : Object.keys(headers) const segment = transaction.agent.tracer.getSegment() for (let i = 0; i < headerKeys.length; i++) { const headerKey = headerKeys[i] let header = headers[headerKey] if (header !== undefined) { // If any more processing of the headers is required consider refactoring this. if (headerKey === 'referer' && typeof header === 'string') { const queryParamIndex = header.indexOf('?') if (queryParamIndex !== -1) { header = header.substring(0, queryParamIndex) } } const attributeName = nameMap[headerKey] || prefix + _headerToCamelCase(headerKey) transaction.trace.attributes.addAttribute(DESTS.TRANS_COMMON, attributeName, header) segment.addSpanAttribute(attributeName, header) } } } /** * Adds request headers as request.headers.* attributes to the given transaction. * * @param {Object<string, string>} headers - Request headers to add attributes for. * @param {Transaction} transaction - Transaction to add header attributes to. */ function collectRequestHeaders(headers, transaction) { _collectHeaders(headers, REQUEST_HEADER_NAMES, REQUEST_HEADER_PREFIX, transaction) } /** * Adds response headers as response.headers.* attributes to the given transaction. * * @param {Object<string, string>} headers - Response headers to add attributes for. * @param {Transaction} transaction - Transaction to add header attributes to. */ function collectResponseHeaders(headers, transaction) { _collectHeaders(headers, RESPONSE_HEADER_NAMES, RESPONSE_HEADER_PREFIX, transaction) } module.exports = { collectRequestHeaders, collectResponseHeaders }