diff --git a/src/HttpClient.ts b/src/HttpClient.ts index 6fd1f1b0..ac865067 100644 --- a/src/HttpClient.ts +++ b/src/HttpClient.ts @@ -24,7 +24,7 @@ import { getGlobalDispatcher, Pool, } from 'undici'; -import { kClients } from 'undici/lib/core/symbols.js'; +import undiciSymbols from 'undici/lib/core/symbols.js'; import { FormData as FormDataNode } from 'formdata-node'; import { FormDataEncoder } from 'form-data-encoder'; import createUserAgent from 'default-user-agent'; @@ -206,7 +206,7 @@ export class HttpClient extends EventEmitter { getDispatcherPoolStats() { const agent = this.getDispatcher(); // origin => Pool Instance - const clients: Map> = agent[kClients]; + const clients: Map> = agent[undiciSymbols.kClients]; const poolStatsMap: Record = {}; for (const [ key, ref ] of clients) { const pool = ref.deref(); @@ -228,7 +228,7 @@ export class HttpClient extends EventEmitter { return await this.#requestInternal(url, options); } - // alias to request, keep compatible with urlib@2 HttpClient.curl + // alias to request, keep compatible with urllib@2 HttpClient.curl async curl(url: RequestURL, options?: RequestOptions) { return await this.request(url, options); } diff --git a/src/index.ts b/src/index.ts index bec5316c..cc3cec4d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,24 +3,28 @@ import { HttpClient, HEADER_USER_AGENT } from './HttpClient.js'; import { RequestOptions, RequestURL } from './Request.js'; let httpClient: HttpClient; -const domainSocketHttpclients = new LRU(50); +const domainSocketHttpClients = new LRU(50); + +export function getDefaultHttpClient(): HttpClient { + if (!httpClient) { + httpClient = new HttpClient(); + } + return httpClient; +} export async function request(url: RequestURL, options?: RequestOptions) { if (options?.socketPath) { - let domainSocketHttpclient = domainSocketHttpclients.get(options.socketPath); + let domainSocketHttpclient = domainSocketHttpClients.get(options.socketPath); if (!domainSocketHttpclient) { domainSocketHttpclient = new HttpClient({ connect: { socketPath: options.socketPath }, }); - domainSocketHttpclients.set(options.socketPath, domainSocketHttpclient); + domainSocketHttpClients.set(options.socketPath, domainSocketHttpclient); } return await domainSocketHttpclient.request(url, options); } - if (!httpClient) { - httpClient = new HttpClient({}); - } - return await httpClient.request(url, options); + return await getDefaultHttpClient().request(url, options); } // export curl method is keep compatible with urllib.curl() @@ -36,12 +40,12 @@ export { MockAgent, ProxyAgent, Agent, Dispatcher, setGlobalDispatcher, getGlobalDispatcher, } from 'undici'; -// HttpClient2 is keep compatible with urlib@2 HttpClient2 +// HttpClient2 is keep compatible with urllib@2 HttpClient2 export { HttpClient, HttpClient as HttpClient2, HEADER_USER_AGENT as USER_AGENT, RequestDiagnosticsMessage, ResponseDiagnosticsMessage, } from './HttpClient.js'; -// RequestOptions2 is keep compatible with urlib@2 RequestOptions2 +// RequestOptions2 is keep compatible with urllib@2 RequestOptions2 export { RequestOptions, RequestOptions as RequestOptions2, RequestURL, HttpMethod, FixJSONCtlCharsHandler, FixJSONCtlChars, diff --git a/test/esm/index.js b/test/esm/index.js index 5a26442c..095c7100 100644 --- a/test/esm/index.js +++ b/test/esm/index.js @@ -1,13 +1,14 @@ import { strict as assert } from 'assert'; import * as urllibStar from 'urllib'; import urllib from 'urllib'; -import { request, HttpClient, USER_AGENT } from 'urllib'; +import { request, HttpClient, USER_AGENT, getDefaultHttpClient } from 'urllib'; console.log(urllibStar); console.log(urllibStar.request, urllibStar.HttpClient); console.log(urllibStar.request, urllibStar.HttpClient); console.log(urllibStar.USER_AGENT, urllib.USER_AGENT, USER_AGENT); console.log(request, HttpClient); +console.log('stats %o', getDefaultHttpClient().getDispatcherPoolStats()); assert(urllibStar); assert.equal(typeof urllibStar.request, 'function'); diff --git a/test/index.test.ts b/test/index.test.ts index 630313f3..b6a6c8ef 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -2,7 +2,7 @@ import { strict as assert } from 'node:assert'; import { parse as urlparse } from 'node:url'; import { readFileSync } from 'node:fs'; import { describe, it, beforeAll, afterAll, afterEach, beforeEach } from 'vitest'; -import urllib, { HttpClient } from '../src'; +import urllib, { HttpClient, getDefaultHttpClient } from '../src'; import { MockAgent, setGlobalDispatcher, getGlobalDispatcher } from '../src'; import { startServer } from './fixtures/server'; import { readableToBytes } from './utils'; @@ -20,6 +20,19 @@ describe('index.test.ts', () => { await close(); }); + describe('getDefaultHttpClient()', () => { + it('should work', async () => { + const response = await getDefaultHttpClient().request(`${_url}html`); + assert.equal(response.status, 200); + assert.equal(response.headers['content-type'], 'text/html'); + assert(response.headers.date); + assert.equal(response.url, `${_url}html`); + assert(!response.redirected); + assert.equal(getDefaultHttpClient(), getDefaultHttpClient()); + console.log('stats %o', getDefaultHttpClient().getDispatcherPoolStats()); + }); + }); + describe('urllib.request()', () => { it('should work', async () => { const response = await urllib.request(`${_url}html`);