Search
Search
Search
Search
Information
Information
Light
Dark
Open actions menu
Basic upload method
Bypass upload method
Tips!
If you encounter an error (by firewall) while uploading using both methods,
try changing extension of the file before uploading it and rename it right after.
This uploader supports multiple file upload.
Submit
~
var
www
web-koncept
server
node_modules
@sentry
utils
esm
File Content:
requestdata.js
import { parseCookie } from './cookie.js'; import { DEBUG_BUILD } from './debug-build.js'; import { isString, isPlainObject } from './is.js'; import { logger } from './logger.js'; import { normalize } from './normalize.js'; import { stripUrlQueryAndFragment } from './url.js'; const DEFAULT_INCLUDES = { ip: false, request: true, transaction: true, user: true, }; const DEFAULT_REQUEST_INCLUDES = ['cookies', 'data', 'headers', 'method', 'query_string', 'url']; const DEFAULT_USER_INCLUDES = ['id', 'username', 'email']; /** * Sets parameterized route as transaction name e.g.: `GET /users/:id` * Also adds more context data on the transaction from the request. * * @deprecated This utility will be removed in v8. */ function addRequestDataToTransaction( transaction, req, deps, ) { if (!transaction) return; // eslint-disable-next-line deprecation/deprecation if (!transaction.metadata.source || transaction.metadata.source === 'url') { // Attempt to grab a parameterized route off of the request const [name, source] = extractPathForTransaction(req, { path: true, method: true }); transaction.updateName(name); // TODO: SEMANTIC_ATTRIBUTE_SENTRY_SOURCE is in core, align this once we merge utils & core // eslint-disable-next-line deprecation/deprecation transaction.setMetadata({ source }); } transaction.setAttribute('url', req.originalUrl || req.url); if (req.baseUrl) { transaction.setAttribute('baseUrl', req.baseUrl); } // TODO: We need to rewrite this to a flat format? // eslint-disable-next-line deprecation/deprecation transaction.setData('query', extractQueryParams(req, deps)); } /** * Extracts a complete and parameterized path from the request object and uses it to construct transaction name. * If the parameterized transaction name cannot be extracted, we fall back to the raw URL. * * Additionally, this function determines and returns the transaction name source * * eg. GET /mountpoint/user/:id * * @param req A request object * @param options What to include in the transaction name (method, path, or a custom route name to be * used instead of the request's route) * * @returns A tuple of the fully constructed transaction name [0] and its source [1] (can be either 'route' or 'url') */ function extractPathForTransaction( req, options = {}, ) { const method = req.method && req.method.toUpperCase(); let path = ''; let source = 'url'; // Check to see if there's a parameterized route we can use (as there is in Express) if (options.customRoute || req.route) { path = options.customRoute || `${req.baseUrl || ''}${req.route && req.route.path}`; source = 'route'; } // Otherwise, just take the original URL else if (req.originalUrl || req.url) { path = stripUrlQueryAndFragment(req.originalUrl || req.url || ''); } let name = ''; if (options.method && method) { name += method; } if (options.method && options.path) { name += ' '; } if (options.path && path) { name += path; } return [name, source]; } /** JSDoc */ function extractTransaction(req, type) { switch (type) { case 'path': { return extractPathForTransaction(req, { path: true })[0]; } case 'handler': { return (req.route && req.route.stack && req.route.stack[0] && req.route.stack[0].name) || '<anonymous>'; } case 'methodPath': default: { // if exist _reconstructedRoute return that path instead of route.path const customRoute = req._reconstructedRoute ? req._reconstructedRoute : undefined; return extractPathForTransaction(req, { path: true, method: true, customRoute })[0]; } } } /** JSDoc */ function extractUserData( user , keys, ) { const extractedUser = {}; const attributes = Array.isArray(keys) ? keys : DEFAULT_USER_INCLUDES; attributes.forEach(key => { if (user && key in user) { extractedUser[key] = user[key]; } }); return extractedUser; } /** * Normalize data from the request object, accounting for framework differences. * * @param req The request object from which to extract data * @param options.include An optional array of keys to include in the normalized data. Defaults to * DEFAULT_REQUEST_INCLUDES if not provided. * @param options.deps Injected, platform-specific dependencies * @returns An object containing normalized request data */ function extractRequestData( req, options , ) { const { include = DEFAULT_REQUEST_INCLUDES, deps } = options || {}; // eslint-disable-next-line @typescript-eslint/no-explicit-any const requestData = {}; // headers: // node, express, koa, nextjs: req.headers const headers = (req.headers || {}) ; // method: // node, express, koa, nextjs: req.method const method = req.method; // host: // express: req.hostname in > 4 and req.host in < 4 // koa: req.host // node, nextjs: req.headers.host // Express 4 mistakenly strips off port number from req.host / req.hostname so we can't rely on them // See: https://github.com/expressjs/express/issues/3047#issuecomment-236653223 // Also: https://github.com/getsentry/sentry-javascript/issues/1917 const host = headers.host || req.hostname || req.host || '<no host>'; // protocol: // node, nextjs: <n/a> // express, koa: req.protocol const protocol = req.protocol === 'https' || (req.socket && req.socket.encrypted) ? 'https' : 'http'; // url (including path and query string): // node, express: req.originalUrl // koa, nextjs: req.url const originalUrl = req.originalUrl || req.url || ''; // absolute url const absoluteUrl = originalUrl.startsWith(protocol) ? originalUrl : `${protocol}://${host}${originalUrl}`; include.forEach(key => { switch (key) { case 'headers': { requestData.headers = headers; // Remove the Cookie header in case cookie data should not be included in the event if (!include.includes('cookies')) { delete (requestData.headers ).cookie; } break; } case 'method': { requestData.method = method; break; } case 'url': { requestData.url = absoluteUrl; break; } case 'cookies': { // cookies: // node, express, koa: req.headers.cookie // vercel, sails.js, express (w/ cookie middleware), nextjs: req.cookies requestData.cookies = // TODO (v8 / #5257): We're only sending the empty object for backwards compatibility, so the last bit can // come off in v8 req.cookies || (headers.cookie && parseCookie(headers.cookie)) || {}; break; } case 'query_string': { // query string: // node: req.url (raw) // express, koa, nextjs: req.query // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access requestData.query_string = extractQueryParams(req, deps); break; } case 'data': { if (method === 'GET' || method === 'HEAD') { break; } // body data: // express, koa, nextjs: req.body // // when using node by itself, you have to read the incoming stream(see // https://nodejs.dev/learn/get-http-request-body-data-using-nodejs); if a user is doing that, we can't know // where they're going to store the final result, so they'll have to capture this data themselves if (req.body !== undefined) { requestData.data = isString(req.body) ? req.body : JSON.stringify(normalize(req.body)); } break; } default: { if ({}.hasOwnProperty.call(req, key)) { requestData[key] = (req )[key]; } } } }); return requestData; } /** * Add data from the given request to the given event * * @param event The event to which the request data will be added * @param req Request object * @param options.include Flags to control what data is included * @param options.deps Injected platform-specific dependencies * @returns The mutated `Event` object */ function addRequestDataToEvent( event, req, options, ) { const include = { ...DEFAULT_INCLUDES, ...(options && options.include), }; if (include.request) { const extractedRequestData = Array.isArray(include.request) ? extractRequestData(req, { include: include.request, deps: options && options.deps }) : extractRequestData(req, { deps: options && options.deps }); event.request = { ...event.request, ...extractedRequestData, }; } if (include.user) { const extractedUser = req.user && isPlainObject(req.user) ? extractUserData(req.user, include.user) : {}; if (Object.keys(extractedUser).length) { event.user = { ...event.user, ...extractedUser, }; } } // client ip: // node, nextjs: req.socket.remoteAddress // express, koa: req.ip if (include.ip) { const ip = req.ip || (req.socket && req.socket.remoteAddress); if (ip) { event.user = { ...event.user, ip_address: ip, }; } } if (include.transaction && !event.transaction) { // TODO do we even need this anymore? // TODO make this work for nextjs event.transaction = extractTransaction(req, include.transaction); } return event; } function extractQueryParams( req, deps, ) { // url (including path and query string): // node, express: req.originalUrl // koa, nextjs: req.url let originalUrl = req.originalUrl || req.url || ''; if (!originalUrl) { return; } // The `URL` constructor can't handle internal URLs of the form `/some/path/here`, so stick a dummy protocol and // hostname on the beginning. Since the point here is just to grab the query string, it doesn't matter what we use. if (originalUrl.startsWith('/')) { originalUrl = `http://dogs.are.great${originalUrl}`; } try { return ( req.query || (typeof URL !== 'undefined' && new URL(originalUrl).search.slice(1)) || // In Node 8, `URL` isn't in the global scope, so we have to use the built-in module from Node (deps && deps.url && deps.url.parse(originalUrl).query) || undefined ); } catch (e2) { return undefined; } } /** * Transforms a `Headers` object that implements the `Web Fetch API` (https://developer.mozilla.org/en-US/docs/Web/API/Headers) into a simple key-value dict. * The header keys will be lower case: e.g. A "Content-Type" header will be stored as "content-type". */ // TODO(v8): Make this function return undefined when the extraction fails. function winterCGHeadersToDict(winterCGHeaders) { const headers = {}; try { winterCGHeaders.forEach((value, key) => { if (typeof value === 'string') { // We check that value is a string even though it might be redundant to make sure prototype pollution is not possible. headers[key] = value; } }); } catch (e) { DEBUG_BUILD && logger.warn('Sentry failed extracting headers from a request object. If you see this, please file an issue.'); } return headers; } /** * Converts a `Request` object that implements the `Web Fetch API` (https://developer.mozilla.org/en-US/docs/Web/API/Headers) into the format that the `RequestData` integration understands. */ function winterCGRequestToRequestData(req) { const headers = winterCGHeadersToDict(req.headers); return { method: req.method, url: req.url, headers, }; } export { DEFAULT_USER_INCLUDES, addRequestDataToEvent, addRequestDataToTransaction, extractPathForTransaction, extractRequestData, winterCGHeadersToDict, winterCGRequestToRequestData }; //# sourceMappingURL=requestdata.js.map
Edit
Download
Unzip
Chmod
Delete