UNPKG

atatus-nodejs

Version:

Atatus APM agent for Node.js

170 lines (149 loc) 3.75 kB
'use strict' var _MAX_HTTP_BODY_CHARS = 20480 // expose for testing purposes function totalChunkLength(chunk1, chunk2) { var length1 = chunk1 ? chunk1.length || 0 : 0 var length2 = chunk2 ? chunk2.length || 0 : 0 return length1 + length2 } function appendChunk(buf, chunk) { if (chunk) { if (Buffer.isBuffer(chunk)) { try { return buf ? Buffer.concat([buf, chunk]) : Buffer.from(chunk) } catch (err) { return buf } } else if (typeof chunk === 'string') { try { return buf ? Buffer.concat([buf, Buffer.from(chunk)]) : Buffer.from(chunk) } catch (err) { return buf } } else if (typeof chunk === 'object' || Array.isArray(chunk)) { try { return buf ? Buffer.concat([buf, Buffer.from(JSON.stringify(chunk))]) : Buffer.from(JSON.stringify(chunk)) } catch (err) { return buf } } else { // console.error('body chunk is not a Buffer or String.') return buf } } return buf } function bodyToBase64(body) { if (!body) { return body } if (body === 'BODY_SIZE_EXCEEDED') { return body } if (Buffer.isBuffer(body)) { return body.toString('base64') } else if (typeof body === 'string') { return Buffer.from(body).toString('base64') } else if (typeof body.toString === 'function') { return Buffer.from(body.toString()).toString('base64') } else { return '' } } function getResponseBodyString(body, isCompresssed) { try { if (!body) { return body } var result var length if (isCompresssed) { length = body.length result = bodyToBase64(body) } else if (!Buffer.isBuffer(body) && typeof body === 'object') { // in case of non POJO result = JSON.stringify(body) length = result.length } else { result = body.toString() length = result.length } if (result === 'BODY_SIZE_EXCEEDED' || length > _MAX_HTTP_BODY_CHARS) { result = isCompresssed ? null : 'The response body has exceeded the maximum allowed size.' } return result; } catch (e) { return 'Error: Unable to access the body.' } } function decodeHeaders(header) { try { var keyVal = header.split('\r\n') // Remove Request Line or Status Line keyVal.shift() var obj = {} var i for (i in keyVal) { keyVal[i] = keyVal[i].split(':', 2) if (keyVal[i].length != 2) { continue } obj[keyVal[i][0].trim()] = keyVal[i][1].trim() } return obj } catch (err) { return {} } } function getResponseHeaders(res) { try { if (res.getHeaders) { return res.getHeaders() } try { // access ._headers will result in exception // in some versions fo node. // so must be in try block. if (res._headers) { return res._headers } } catch (err) { } return res.headers || decodeHeaders(res._header) } catch(err) { return {} } } function getSafeHost (req) { try { if (req.getHeader) { return req.getHeader('Host') } if (req._headers) { return req._headers.host } return '' } catch (err) { return '' } } async function eachLimit(items, fn, limit) { const results = [] while (items.length) { const resolved = await Promise.all(items.splice(0, limit).map(fn)) results.push(...resolved) } return results } module.exports = { _MAX_HTTP_BODY_CHARS: _MAX_HTTP_BODY_CHARS, totalChunkLength: totalChunkLength, appendChunk: appendChunk, getResponseBodyString: getResponseBodyString, getResponseHeaders: getResponseHeaders, getSafeHost: getSafeHost, asyncEachLimit: eachLimit }