@@ -521,6 +521,148 @@ describe('Bun Serve Integration', () => {
521521 } ) ;
522522
523523 describe ( 'data collection' , ( ) => {
524+ test ( 'captures client address, port and protocol by default' , async ( ) => {
525+ const server = Bun . serve ( {
526+ async fetch ( _req ) {
527+ return new Response ( 'Bun!' ) ;
528+ } ,
529+ port,
530+ } ) ;
531+
532+ await fetch ( `http://localhost:${ port } /` ) ;
533+
534+ await server . stop ( ) ;
535+
536+ expect ( startSpanSpy ) . toHaveBeenCalledTimes ( 1 ) ;
537+ expect ( startSpanSpy ) . toHaveBeenCalledWith (
538+ expect . objectContaining ( {
539+ attributes : expect . objectContaining ( {
540+ 'client.address' : expect . stringMatching ( / ^ ( 1 2 7 \. 0 \. 0 \. 1 | : : 1 | : : f f f f : 1 2 7 \. 0 \. 0 \. 1 ) $ / ) ,
541+ 'client.port' : expect . any ( Number ) ,
542+ 'network.protocol.name' : 'http' ,
543+ } ) ,
544+ } ) ,
545+ expect . any ( Function ) ,
546+ ) ;
547+ } ) ;
548+
549+ test ( 'captures client address on route handlers' , async ( ) => {
550+ const server = Bun . serve ( {
551+ routes : {
552+ '/users/:id' : req => new Response ( `User ${ req . params . id } ` ) ,
553+ } ,
554+ port,
555+ } ) ;
556+
557+ await fetch ( `http://localhost:${ port } /users/123` ) ;
558+
559+ await server . stop ( ) ;
560+
561+ expect ( startSpanSpy ) . toHaveBeenCalledTimes ( 1 ) ;
562+ expect ( startSpanSpy ) . toHaveBeenCalledWith (
563+ expect . objectContaining ( {
564+ attributes : expect . objectContaining ( {
565+ 'client.address' : expect . stringMatching ( / ^ ( 1 2 7 \. 0 \. 0 \. 1 | : : 1 | : : f f f f : 1 2 7 \. 0 \. 0 \. 1 ) $ / ) ,
566+ 'client.port' : expect . any ( Number ) ,
567+ } ) ,
568+ } ) ,
569+ expect . any ( Function ) ,
570+ ) ;
571+ } ) ;
572+
573+ test ( 'prefers the first x-forwarded-for address over the socket address' , async ( ) => {
574+ const server = Bun . serve ( {
575+ async fetch ( _req ) {
576+ return new Response ( 'Bun!' ) ;
577+ } ,
578+ port,
579+ } ) ;
580+
581+ await fetch ( `http://localhost:${ port } /` , {
582+ headers : { 'X-Forwarded-For' : '203.0.113.7, 10.0.0.1' } ,
583+ } ) ;
584+
585+ await server . stop ( ) ;
586+
587+ expect ( startSpanSpy ) . toHaveBeenCalledTimes ( 1 ) ;
588+ expect ( startSpanSpy ) . toHaveBeenCalledWith (
589+ expect . objectContaining ( {
590+ attributes : expect . objectContaining ( {
591+ 'client.address' : '203.0.113.7' ,
592+ } ) ,
593+ } ) ,
594+ expect . any ( Function ) ,
595+ ) ;
596+ } ) ;
597+
598+ test ( 'does not capture client address when userInfo collection is disabled' , async ( ) => {
599+ setupClient ( { dataCollection : { userInfo : false } } ) ;
600+
601+ const server = Bun . serve ( {
602+ async fetch ( _req ) {
603+ return new Response ( 'Bun!' ) ;
604+ } ,
605+ port,
606+ } ) ;
607+
608+ await fetch ( `http://localhost:${ port } /` , {
609+ headers : { 'X-Forwarded-For' : '203.0.113.7' } ,
610+ } ) ;
611+
612+ await server . stop ( ) ;
613+
614+ expect ( startSpanSpy ) . toHaveBeenCalledTimes ( 1 ) ;
615+ expect ( startSpanSpy ) . toHaveBeenCalledWith (
616+ expect . objectContaining ( {
617+ attributes : expect . not . objectContaining ( {
618+ 'client.address' : expect . anything ( ) ,
619+ 'client.port' : expect . anything ( ) ,
620+ } ) ,
621+ } ) ,
622+ expect . any ( Function ) ,
623+ ) ;
624+ expect ( startSpanSpy ) . toHaveBeenCalledWith (
625+ expect . objectContaining ( {
626+ attributes : expect . objectContaining ( {
627+ 'network.protocol.name' : 'http' ,
628+ } ) ,
629+ } ) ,
630+ expect . any ( Function ) ,
631+ ) ;
632+ } ) ;
633+
634+ test ( 'leaves client address unset when the handler gets no server' , async ( ) => {
635+ const server = Bun . serve ( {
636+ async fetch ( _req ) {
637+ return new Response ( 'Bun!' ) ;
638+ } ,
639+ port,
640+ } ) ;
641+
642+ // `server.fetch()` calls the handler with the request only.
643+ const response = await server . fetch ( new Request ( `http://localhost:${ port } /` ) ) ;
644+
645+ await server . stop ( ) ;
646+
647+ expect ( await response . text ( ) ) . toBe ( 'Bun!' ) ;
648+ expect ( startSpanSpy ) . toHaveBeenCalledTimes ( 1 ) ;
649+ expect ( startSpanSpy ) . toHaveBeenCalledWith (
650+ expect . objectContaining ( {
651+ attributes : expect . not . objectContaining ( {
652+ 'client.address' : expect . anything ( ) ,
653+ 'client.port' : expect . anything ( ) ,
654+ } ) ,
655+ } ) ,
656+ expect . any ( Function ) ,
657+ ) ;
658+ expect ( startSpanSpy ) . toHaveBeenCalledWith (
659+ expect . objectContaining ( {
660+ attributes : expect . objectContaining ( { 'network.protocol.name' : 'http' } ) ,
661+ } ) ,
662+ expect . any ( Function ) ,
663+ ) ;
664+ } ) ;
665+
524666 test ( 'keeps PII request headers when dataCollection enables full header collection' , async ( ) => {
525667 setupClient ( { dataCollection : { httpHeaders : { request : true , response : true } } } ) ;
526668
0 commit comments