Skip to content

Commit 629c7a3

Browse files
authored
fix: fix socket info in response (#555)
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Introduced the `BaseAgent` class with enhanced asynchronous local storage capabilities. - Updated `HttpAgent` to extend `BaseAgent`, improving address validation and error handling during dispatch operations. - **Bug Fixes** - Enhanced validation in the `dispatch` method of `HttpAgent` to ensure hostname validity. - **Tests** - Added a new assertion in the fetch tests to verify the local address of the response socket. - **Chores** - Removed the `fetchOpaqueInterceptor` function and associated imports to streamline the codebase. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent 12c4e3c commit 629c7a3

File tree

5 files changed

+41
-29
lines changed

5 files changed

+41
-29
lines changed

src/BaseAgent.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import {
2+
Agent,
3+
Dispatcher,
4+
} from 'undici';
5+
import { AsyncLocalStorage } from 'node:async_hooks';
6+
import { FetchOpaque } from './FetchOpaqueInterceptor.js';
7+
8+
export interface BaseAgentOptions extends Agent.Options {
9+
opaqueLocalStorage?: AsyncLocalStorage<FetchOpaque>;
10+
}
11+
12+
export class BaseAgent extends Agent {
13+
#opaqueLocalStorage?: AsyncLocalStorage<FetchOpaque>;
14+
15+
constructor(options: BaseAgentOptions) {
16+
super(options);
17+
this.#opaqueLocalStorage = options.opaqueLocalStorage;
18+
}
19+
20+
dispatch(options: Agent.DispatchOptions, handler: Dispatcher.DispatchHandler): boolean {
21+
const opaque = this.#opaqueLocalStorage?.getStore();
22+
if (opaque) {
23+
(handler as any).opaque = opaque;
24+
}
25+
return super.dispatch(options, handler);
26+
}
27+
}

src/FetchOpaqueInterceptor.ts

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// const { AsyncLocalStorage } = require('node:async_hooks');
22
import { AsyncLocalStorage } from 'node:async_hooks';
33
import symbols from './symbols.js';
4-
import { Dispatcher } from 'undici';
54

65
// const RedirectHandler = require('../handler/redirect-handler')
76

@@ -28,14 +27,3 @@ export interface FetchOpaque {
2827
export interface OpaqueInterceptorOptions {
2928
opaqueLocalStorage: AsyncLocalStorage<FetchOpaque>;
3029
}
31-
32-
export function fetchOpaqueInterceptor(opts: OpaqueInterceptorOptions) {
33-
const opaqueLocalStorage = opts?.opaqueLocalStorage;
34-
return (dispatch: Dispatcher['dispatch']): Dispatcher['dispatch'] => {
35-
return function redirectInterceptor(opts: Dispatcher.DispatchOptions, handler: Dispatcher.DispatchHandler) {
36-
const opaque = opaqueLocalStorage?.getStore();
37-
(handler as any).opaque = opaque;
38-
return dispatch(opts, handler);
39-
};
40-
};
41-
}

src/HttpAgent.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@ import {
55
Dispatcher,
66
buildConnector,
77
} from 'undici';
8+
import { BaseAgent, BaseAgentOptions } from './BaseAgent.js';
89

910
export type CheckAddressFunction = (ip: string, family: number | string, hostname: string) => boolean;
1011

11-
export interface HttpAgentOptions extends Agent.Options {
12+
export interface HttpAgentOptions extends BaseAgentOptions {
1213
lookup?: LookupFunction;
1314
checkAddress?: CheckAddressFunction;
1415
connect?: buildConnector.BuildOptions,
@@ -31,7 +32,7 @@ class IllegalAddressError extends Error {
3132
}
3233
}
3334

34-
export class HttpAgent extends Agent {
35+
export class HttpAgent extends BaseAgent {
3536
#checkAddress?: CheckAddressFunction;
3637

3738
constructor(options: HttpAgentOptions) {

src/fetch.ts

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
Agent,
99
getGlobalDispatcher,
1010
Pool,
11+
Dispatcher,
1112
} from 'undici';
1213
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
1314
// @ts-ignore
@@ -35,9 +36,10 @@ import {
3536
HttpMethod,
3637
RequestMeta,
3738
} from './Request.js';
38-
import { FetchOpaque, fetchOpaqueInterceptor } from './FetchOpaqueInterceptor.js';
39+
import { FetchOpaque } from './FetchOpaqueInterceptor.js';
3940
import { RawResponseWithMeta, SocketInfo } from './Response.js';
4041
import { IncomingHttpHeaders } from './IncomingHttpHeaders.js';
42+
import { BaseAgent, BaseAgentOptions } from './BaseAgent.js';
4143

4244
export interface UrllibRequestInit extends RequestInit {
4345
// default is true
@@ -56,7 +58,7 @@ export type FetchResponseDiagnosticsMessage = {
5658
};
5759

5860
export class FetchFactory {
59-
static #dispatcher: Agent;
61+
static #dispatcher: Dispatcher.ComposedDispatcher;
6062
static #opaqueLocalStorage = new AsyncLocalStorage<FetchOpaque>();
6163

6264
static getDispatcher() {
@@ -68,17 +70,10 @@ export class FetchFactory {
6870
}
6971

7072
static setClientOptions(clientOptions: ClientOptions) {
71-
let dispatcherOption: Agent.Options = {
72-
interceptors: {
73-
Agent: [
74-
fetchOpaqueInterceptor({
75-
opaqueLocalStorage: FetchFactory.#opaqueLocalStorage,
76-
}),
77-
],
78-
Client: [],
79-
},
73+
let dispatcherOption: BaseAgentOptions = {
74+
opaqueLocalStorage: FetchFactory.#opaqueLocalStorage,
8075
};
81-
let dispatcherClazz: new (options: Agent.Options) => Agent = Agent;
76+
let dispatcherClazz: new (options: BaseAgentOptions) => BaseAgent = BaseAgent;
8277
if (clientOptions?.lookup || clientOptions?.checkAddress) {
8378
dispatcherOption = {
8479
...dispatcherOption,
@@ -87,21 +82,21 @@ export class FetchFactory {
8782
connect: clientOptions.connect,
8883
allowH2: clientOptions.allowH2,
8984
} as HttpAgentOptions;
90-
dispatcherClazz = HttpAgent as unknown as new (options: Agent.Options) => Agent;
85+
dispatcherClazz = HttpAgent as unknown as new (options: BaseAgentOptions) => BaseAgent;
9186
} else if (clientOptions?.connect) {
9287
dispatcherOption = {
9388
...dispatcherOption,
9489
connect: clientOptions.connect,
9590
allowH2: clientOptions.allowH2,
9691
} as HttpAgentOptions;
97-
dispatcherClazz = Agent;
92+
dispatcherClazz = BaseAgent;
9893
} else if (clientOptions?.allowH2) {
9994
// Support HTTP2
10095
dispatcherOption = {
10196
...dispatcherOption,
10297
allowH2: clientOptions.allowH2,
10398
} as HttpAgentOptions;
104-
dispatcherClazz = Agent;
99+
dispatcherClazz = BaseAgent;
105100
}
106101
FetchFactory.#dispatcher = new dispatcherClazz(dispatcherOption);
107102
initDiagnosticsChannel();

test/fetch.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ describe('fetch.test.ts', () => {
4646
assert(requestDiagnosticsMessage!.request);
4747
assert(responseDiagnosticsMessage!.request);
4848
assert(responseDiagnosticsMessage!.response);
49+
assert([ '127.0.0.1', '::1' ].includes(responseDiagnosticsMessage!.response.socket.localAddress));
4950

5051
assert(fetchDiagnosticsMessage!.fetch);
5152
assert(fetchResponseDiagnosticsMessage!.fetch);

0 commit comments

Comments
 (0)