@@ -68,6 +68,71 @@ describe("SSEClientTransport", () => {
6868 } ) ;
6969
7070 describe ( "connection handling" , ( ) => {
71+ it ( "maintains custom path when constructing endpoint URL" , async ( ) => {
72+ // Create a URL with a custom path
73+ const customPathUrl = new URL ( "/custom/path/sse" , baseUrl ) ;
74+ transport = new SSEClientTransport ( customPathUrl ) ;
75+
76+ // Start the transport
77+ await transport . start ( ) ;
78+
79+ // Send a test message to verify the endpoint URL
80+ const message : JSONRPCMessage = {
81+ jsonrpc : "2.0" ,
82+ id : "test-1" ,
83+ method : "test" ,
84+ params : { }
85+ } ;
86+
87+ await transport . send ( message ) ;
88+
89+ // Verify the POST request maintains the custom path
90+ expect ( lastServerRequest . url ) . toBe ( "/custom/path/messages" ) ;
91+ } ) ;
92+
93+ it ( "handles multiple levels of custom paths" , async ( ) => {
94+ // Test with a deeper nested path
95+ const nestedPathUrl = new URL ( "/api/v1/custom/deep/path/sse" , baseUrl ) ;
96+ transport = new SSEClientTransport ( nestedPathUrl ) ;
97+
98+ await transport . start ( ) ;
99+
100+ const message : JSONRPCMessage = {
101+ jsonrpc : "2.0" ,
102+ id : "test-1" ,
103+ method : "test" ,
104+ params : { }
105+ } ;
106+
107+ await transport . send ( message ) ;
108+
109+ // Verify the POST request maintains the full custom path
110+ expect ( lastServerRequest . url ) . toBe ( "/api/v1/custom/deep/path/messages" ) ;
111+ } ) ;
112+
113+ it ( "maintains custom path for SSE connection" , async ( ) => {
114+ const customPathUrl = new URL ( "/custom/path/sse" , baseUrl ) ;
115+ transport = new SSEClientTransport ( customPathUrl ) ;
116+ await transport . start ( ) ;
117+ expect ( lastServerRequest . url ) . toBe ( "/custom/path/sse" ) ;
118+ } ) ;
119+
120+ it ( "handles URLs with query parameters" , async ( ) => {
121+ const urlWithQuery = new URL ( "/custom/path/sse?param=value" , baseUrl ) ;
122+ transport = new SSEClientTransport ( urlWithQuery ) ;
123+ await transport . start ( ) ;
124+
125+ const message : JSONRPCMessage = {
126+ jsonrpc : "2.0" ,
127+ id : "test-1" ,
128+ method : "test" ,
129+ params : { }
130+ } ;
131+
132+ await transport . send ( message ) ;
133+ expect ( lastServerRequest . url ) . toBe ( "/custom/path/messages" ) ;
134+ } ) ;
135+
71136 it ( "establishes SSE connection and receives endpoint" , async ( ) => {
72137 transport = new SSEClientTransport ( baseUrl ) ;
73138 await transport . start ( ) ;
@@ -397,18 +462,18 @@ describe("SSEClientTransport", () => {
397462 return ;
398463 }
399464
400- res . writeHead ( 200 , {
401- "Content-Type" : "text/event-stream" ,
402- "Cache-Control" : "no-cache, no-transform" ,
403- Connection : "keep-alive" ,
404- } ) ;
405- res . write ( "event: endpoint\n" ) ;
406- res . write ( `data: ${ baseUrl . href } \n\n` ) ;
465+ res . writeHead ( 200 , {
466+ "Content-Type" : "text/event-stream" ,
467+ "Cache-Control" : "no-cache, no-transform" ,
468+ Connection : "keep-alive" ,
469+ } ) ;
470+ res . write ( "event: endpoint\n" ) ;
471+ res . write ( `data: ${ baseUrl . href } \n\n` ) ;
407472 break ;
408473
409474 case "POST" :
410- res . writeHead ( 401 ) ;
411- res . end ( ) ;
475+ res . writeHead ( 401 ) ;
476+ res . end ( ) ;
412477 break ;
413478 }
414479 } ) ;
@@ -517,25 +582,25 @@ describe("SSEClientTransport", () => {
517582 return ;
518583 }
519584
520- const auth = req . headers . authorization ;
521- if ( auth === "Bearer expired-token" ) {
522- res . writeHead ( 401 ) . end ( ) ;
523- return ;
524- }
585+ const auth = req . headers . authorization ;
586+ if ( auth === "Bearer expired-token" ) {
587+ res . writeHead ( 401 ) . end ( ) ;
588+ return ;
589+ }
525590
526- if ( auth === "Bearer new-token" ) {
527- res . writeHead ( 200 , {
528- "Content-Type" : "text/event-stream" ,
529- "Cache-Control" : "no-cache, no-transform" ,
530- Connection : "keep-alive" ,
531- } ) ;
532- res . write ( "event: endpoint\n" ) ;
533- res . write ( `data: ${ baseUrl . href } \n\n` ) ;
534- connectionAttempts ++ ;
535- return ;
536- }
591+ if ( auth === "Bearer new-token" ) {
592+ res . writeHead ( 200 , {
593+ "Content-Type" : "text/event-stream" ,
594+ "Cache-Control" : "no-cache, no-transform" ,
595+ Connection : "keep-alive" ,
596+ } ) ;
597+ res . write ( "event: endpoint\n" ) ;
598+ res . write ( `data: ${ baseUrl . href } \n\n` ) ;
599+ connectionAttempts ++ ;
600+ return ;
601+ }
537602
538- res . writeHead ( 401 ) . end ( ) ;
603+ res . writeHead ( 401 ) . end ( ) ;
539604 } ) ;
540605
541606 await new Promise < void > ( resolve => {
@@ -610,13 +675,13 @@ describe("SSEClientTransport", () => {
610675 return ;
611676 }
612677
613- res . writeHead ( 200 , {
614- "Content-Type" : "text/event-stream" ,
615- "Cache-Control" : "no-cache, no-transform" ,
616- Connection : "keep-alive" ,
617- } ) ;
618- res . write ( "event: endpoint\n" ) ;
619- res . write ( `data: ${ baseUrl . href } \n\n` ) ;
678+ res . writeHead ( 200 , {
679+ "Content-Type" : "text/event-stream" ,
680+ "Cache-Control" : "no-cache, no-transform" ,
681+ Connection : "keep-alive" ,
682+ } ) ;
683+ res . write ( "event: endpoint\n" ) ;
684+ res . write ( `data: ${ baseUrl . href } \n\n` ) ;
620685 break ;
621686
622687 case "POST" : {
@@ -625,19 +690,19 @@ describe("SSEClientTransport", () => {
625690 return ;
626691 }
627692
628- const auth = req . headers . authorization ;
629- if ( auth === "Bearer expired-token" ) {
630- res . writeHead ( 401 ) . end ( ) ;
631- return ;
632- }
693+ const auth = req . headers . authorization ;
694+ if ( auth === "Bearer expired-token" ) {
695+ res . writeHead ( 401 ) . end ( ) ;
696+ return ;
697+ }
633698
634- if ( auth === "Bearer new-token" ) {
635- res . writeHead ( 200 ) . end ( ) ;
636- postAttempts ++ ;
637- return ;
638- }
699+ if ( auth === "Bearer new-token" ) {
700+ res . writeHead ( 200 ) . end ( ) ;
701+ postAttempts ++ ;
702+ return ;
703+ }
639704
640- res . writeHead ( 401 ) . end ( ) ;
705+ res . writeHead ( 401 ) . end ( ) ;
641706 break ;
642707 }
643708 }
0 commit comments