From 7aeb24e83d07702817d7a6b75147523a597a0683 Mon Sep 17 00:00:00 2001 From: Anthony nguyen Date: Fri, 11 Apr 2025 18:23:39 -0700 Subject: [PATCH 1/5] add custom headers on initial _startOrAuth call --- src/client/sse.test.ts | 23 +++++++++++++++++++++++ src/client/sse.ts | 18 +++++++++++------- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/src/client/sse.test.ts b/src/client/sse.test.ts index 77b28508..5976633a 100644 --- a/src/client/sse.test.ts +++ b/src/client/sse.test.ts @@ -329,6 +329,29 @@ describe("SSEClientTransport", () => { expect(mockAuthProvider.tokens).toHaveBeenCalled(); }); + it("attaches custom header from provider on initial SSE connection", async () => { + mockAuthProvider.tokens.mockResolvedValue({ + access_token: "test-token", + token_type: "Bearer" + }); + const customHeaders = { + "X-Custom-Header": "custom-value", + }; + + transport = new SSEClientTransport(baseUrl, { + authProvider: mockAuthProvider, + requestInit: { + headers: customHeaders, + }, + }); + + await transport.start(); + + expect(lastServerRequest.headers.authorization).toBe("Bearer test-token"); + expect(lastServerRequest.headers["x-custom-header"]).toBe("custom-value"); + expect(mockAuthProvider.tokens).toHaveBeenCalled(); + }); + it("attaches auth header from provider on POST requests", async () => { mockAuthProvider.tokens.mockResolvedValue({ access_token: "test-token", diff --git a/src/client/sse.ts b/src/client/sse.ts index 5e9f0cf0..7e2c2d81 100644 --- a/src/client/sse.ts +++ b/src/client/sse.ts @@ -113,13 +113,17 @@ export class SSEClientTransport implements Transport { this._eventSource = new EventSource( this._url.href, this._eventSourceInit ?? { - fetch: (url, init) => this._commonHeaders().then((headers) => fetch(url, { - ...init, - headers: { - ...headers, - Accept: "text/event-stream" - } - })), + fetch: async (url, init) => { + const commonHeaders = await this._commonHeaders(); + const allHeaders = { ...commonHeaders, ...this._requestInit?.headers}; + return fetch(url, { + ...init, + headers: { + ...allHeaders, + Accept: "text/event-stream" + } + }) + } }, ); this._abortController = new AbortController(); From bc357cb90e84c332b3c935a4c75a88f59258b493 Mon Sep 17 00:00:00 2001 From: Olivier Chafik Date: Mon, 7 Jul 2025 11:01:53 +0100 Subject: [PATCH 2/5] update client/sse.ts: align commonHeaders w/ streamableHttp version --- src/client/sse.ts | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/client/sse.ts b/src/client/sse.ts index 7e2c2d81..0aac0313 100644 --- a/src/client/sse.ts +++ b/src/client/sse.ts @@ -96,7 +96,7 @@ export class SSEClientTransport implements Transport { return await this._startOrAuth(); } - private async _commonHeaders(): Promise { + private async _commonHeaders(): Promise { const headers: HeadersInit = {}; if (this._authProvider) { const tokens = await this._authProvider.tokens(); @@ -105,7 +105,9 @@ export class SSEClientTransport implements Transport { } } - return headers; + return new Headers( + { ...headers, ...this._requestInit?.headers } + ); } private _startOrAuth(): Promise { @@ -114,14 +116,11 @@ export class SSEClientTransport implements Transport { this._url.href, this._eventSourceInit ?? { fetch: async (url, init) => { - const commonHeaders = await this._commonHeaders(); - const allHeaders = { ...commonHeaders, ...this._requestInit?.headers}; + const headers = await this._commonHeaders(); + headers.set("Accept", "text/event-stream"); return fetch(url, { ...init, - headers: { - ...allHeaders, - Accept: "text/event-stream" - } + headers, }) } }, @@ -215,8 +214,7 @@ export class SSEClientTransport implements Transport { } try { - const commonHeaders = await this._commonHeaders(); - const headers = new Headers({ ...commonHeaders, ...this._requestInit?.headers }); + const headers = await this._commonHeaders(); headers.set("content-type", "application/json"); const init = { ...this._requestInit, From 6aee4d73710bcaaa3ca7a3b60b4b6383929d25d3 Mon Sep 17 00:00:00 2001 From: Olivier Chafik Date: Mon, 7 Jul 2025 11:12:21 +0100 Subject: [PATCH 3/5] sse.ts: fix merge --- src/client/sse.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/client/sse.ts b/src/client/sse.ts index ab231147..743fdcf5 100644 --- a/src/client/sse.ts +++ b/src/client/sse.ts @@ -106,10 +106,8 @@ export class SSEClientTransport implements Transport { return await this._startOrAuth(); } - private async _commonHeaders(): Promise { - const headers = { - ...this._requestInit?.headers, - } as HeadersInit & Record; + private async _commonHeaders(): Promise { + const headers: HeadersInit = {}; if (this._authProvider) { const tokens = await this._authProvider.tokens(); if (tokens) { @@ -126,7 +124,7 @@ export class SSEClientTransport implements Transport { } private _startOrAuth(): Promise { -const fetchImpl = (this?._eventSourceInit?.fetch ?? this._fetch ?? fetch) as typeof fetch + const fetchImpl = (this?._eventSourceInit?.fetch ?? this._fetch ?? fetch) as typeof fetch return new Promise((resolve, reject) => { this._eventSource = new EventSource( this._url.href, From e96a96236ebd5be25e0eb495a33d0b0eaca9132f Mon Sep 17 00:00:00 2001 From: Olivier Chafik Date: Mon, 7 Jul 2025 11:12:50 +0100 Subject: [PATCH 4/5] sse.test.ts: fix merge --- src/client/sse.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/sse.test.ts b/src/client/sse.test.ts index 2981356e..3e3abe68 100644 --- a/src/client/sse.test.ts +++ b/src/client/sse.test.ts @@ -391,7 +391,7 @@ describe("SSEClientTransport", () => { "X-Custom-Header": "custom-value", }; - transport = new SSEClientTransport(baseUrl, { + transport = new SSEClientTransport(resourceBaseUrl, { authProvider: mockAuthProvider, requestInit: { headers: customHeaders, From 68c8f8d12d76fa4c2672d8061dacdf4109049e0e Mon Sep 17 00:00:00 2001 From: Olivier Chafik Date: Mon, 7 Jul 2025 11:27:44 +0100 Subject: [PATCH 5/5] sse.ts: fix merge --- src/client/sse.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/client/sse.ts b/src/client/sse.ts index 743fdcf5..568a5159 100644 --- a/src/client/sse.ts +++ b/src/client/sse.ts @@ -135,10 +135,7 @@ export class SSEClientTransport implements Transport { headers.set("Accept", "text/event-stream"); const response = await fetchImpl(url, { ...init, - headers: new Headers({ - ...headers, - Accept: "text/event-stream" - }) + headers, }) if (response.status === 401 && response.headers.has('www-authenticate')) {