@@ -4,6 +4,7 @@ import { Transport } from "../shared/transport.js";
44import { JSONRPCMessage , JSONRPCMessageSchema } from "../types.js" ;
55import getRawBody from "raw-body" ;
66import contentType from "content-type" ;
7+ import { URL } from 'url' ;
78
89const MAXIMUM_MESSAGE_SIZE = "4mb" ;
910
@@ -49,17 +50,17 @@ export class SSEServerTransport implements Transport {
4950 } ) ;
5051
5152 // Send the endpoint event
52- /**
53- * Determine the appropriate separator for adding the sessionId parameter.
54- * Uses '&' if the endpoint already contains a query parameter (has a '?'),
55- * otherwise uses '?' to start the query string.
56- *
57- * Note: This approach works for standard endpoints but doesn't handle
58- * the edge case where '?' might be part of the path itself.
59- */
60- const separator = this . _endpoint . includes ( '?' ) ? '&' : '?' ;
53+ // Use a dummy base URL because this._endpoint is relative.
54+ // This allows using URL/URLSearchParams for robust parameter handling .
55+ const dummyBase = 'http://localhost' ; // Any valid base works
56+ const endpointUrl = new URL ( this . _endpoint , dummyBase ) ;
57+ endpointUrl . searchParams . set ( 'sessionId' , this . _sessionId ) ;
58+
59+ // Reconstruct the relative URL string (pathname + search + hash)
60+ const relativeUrlWithSession = endpointUrl . pathname + endpointUrl . search + endpointUrl . hash ;
61+
6162 this . res . write (
62- `event: endpoint\ndata: ${ encodeURI ( this . _endpoint ) } ${ separator } sessionId= ${ this . _sessionId } \n\n` ,
63+ `event: endpoint\ndata: ${ relativeUrlWithSession } \n\n` ,
6364 ) ;
6465
6566 this . _sseResponse = this . res ;
0 commit comments