Skip to content
Merged
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
6 changes: 5 additions & 1 deletion packages/nextjs/src/utils/instrumentServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export interface NextRequest extends http.IncomingMessage {
url: string;
query: { [key: string]: string };
headers: { [key: string]: string };
body: string | { [key: string]: unknown };
}
type NextResponse = http.ServerResponse;

Expand Down Expand Up @@ -309,9 +310,12 @@ function shouldTraceRequest(url: string, publicDirFiles: Set<string>): boolean {
* @returns The modified event
*/
export function addRequestDataToEvent(event: SentryEvent, req: NextRequest): SentryEvent {
// TODO (breaking change): Replace all calls to this function with `parseRequest(event, req, { transaction: false })`
// (this is breaking because doing so will change `event.request.url` from a path into an absolute URL, which might
// mess up various automations in the Sentry web app - alert rules, auto assignment, saved searches, etc)
event.request = {
...event.request,
// TODO body/data
data: req.body,
url: req.url.split('?')[0],
cookies: req.cookies,
headers: req.headers,
Expand Down
31 changes: 17 additions & 14 deletions packages/node/src/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,30 +200,30 @@ export function extractRequestData(
const requestData: { [key: string]: any } = {};

// headers:
// node, express: req.headers
// node, express, nextjs: req.headers
// koa: req.header
const headers = (req.headers || req.header || {}) as {
host?: string;
cookie?: string;
};
// method:
// node, express, koa: req.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: req.headers.host
// node, nextjs: req.headers.host
const host = req.hostname || req.host || headers.host || '<no host>';
// protocol:
// node: <n/a>
// node, nextjs: <n/a>
// express, koa: req.protocol
const protocol =
req.protocol === 'https' || req.secure || ((req.socket || {}) as { encrypted?: boolean }).encrypted
? 'https'
: 'http';
// url (including path and query string):
// node, express: req.originalUrl
// koa: req.url
// koa, nextjs: req.url
const originalUrl = (req.originalUrl || req.url || '') as string;
// absolute url
const absoluteUrl = `${protocol}://${host}${originalUrl}`;
Expand All @@ -242,26 +242,27 @@ export function extractRequestData(
case 'cookies':
// cookies:
// node, express, koa: req.headers.cookie
// vercel, sails.js, express (w/ cookie middleware): req.cookies
// vercel, sails.js, express (w/ cookie middleware), nextjs: req.cookies
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
requestData.cookies = req.cookies || cookie.parse(headers.cookie || '');
break;
case 'query_string':
// query string:
// node: req.url (raw)
// express, koa: req.query
// express, koa, nextjs: req.query
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm glad it worked despite incorrect comment 😶

// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
requestData.query_string = url.parse(originalUrl || '', false).query;
requestData.query_string = req.query || url.parse(originalUrl || '', false).query;
break;
case 'data':
if (method === 'GET' || method === 'HEAD') {
break;
}
// body data: express, koa: 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
// 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));
}
Expand Down Expand Up @@ -345,7 +346,7 @@ export function parseRequest(event: Event, req: ExpressRequest, options?: ParseR
}

// client ip:
// node: req.connection.remoteAddress
// node, nextjs: req.connection.remoteAddress
// express, koa: req.ip
if (options.ip) {
const ip = req.ip || (req.connection && req.connection.remoteAddress);
Expand All @@ -358,6 +359,8 @@ export function parseRequest(event: Event, req: ExpressRequest, options?: ParseR
}

if (options.transaction && !event.transaction) {
// TODO do we even need this anymore?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Afair it will be dropped in the next major.

// TODO make this work for nextjs
event.transaction = extractTransaction(req, options.transaction);
}

Expand Down