UNPKG

@push.rocks/smartrequest

Version:

A module for modern HTTP/HTTPS requests with support for form data, file uploads, JSON, binary data, streams, and more.

156 lines 12.1 kB
import * as plugins from './plugins.js'; import * as types from './types.js'; import { CoreResponse } from './response.js'; // Keep-alive agents for connection pooling const httpAgent = new plugins.agentkeepalive.HttpAgent({ keepAlive: true, maxFreeSockets: 10, maxSockets: 100, maxTotalSockets: 1000, }); const httpAgentKeepAliveFalse = new plugins.agentkeepalive.HttpAgent({ keepAlive: false, }); const httpsAgent = new plugins.agentkeepalive.HttpsAgent({ keepAlive: true, maxFreeSockets: 10, maxSockets: 100, maxTotalSockets: 1000, }); const httpsAgentKeepAliveFalse = new plugins.agentkeepalive.HttpsAgent({ keepAlive: false, }); /** * Core Request class that handles all HTTP/HTTPS requests */ export class CoreRequest { /** * Tests if a URL is a unix socket */ static isUnixSocket(url) { const unixRegex = /^(http:\/\/|https:\/\/|)unix:/; return unixRegex.test(url); } /** * Parses socket path and route from unix socket URL */ static parseUnixSocketUrl(url) { const parseRegex = /(.*):(.*)/; const result = parseRegex.exec(url); return { socketPath: result[1], path: result[2], }; } constructor(url, options = {}, requestDataFunc = null) { this.url = url; this.options = options; this.requestDataFunc = requestDataFunc; } /** * Fire the request and return a CoreResponse */ async fire() { const incomingMessage = await this.fireCore(); return new CoreResponse(incomingMessage, this.url); } /** * Fire the request and return the raw IncomingMessage */ async fireCore() { const done = plugins.smartpromise.defer(); // Parse URL const parsedUrl = plugins.smarturl.Smarturl.createFromUrl(this.url, { searchParams: this.options.queryParams || {}, }); this.options.hostname = parsedUrl.hostname; if (parsedUrl.port) { this.options.port = parseInt(parsedUrl.port, 10); } this.options.path = parsedUrl.path; // Handle unix socket URLs if (CoreRequest.isUnixSocket(this.url)) { const { socketPath, path } = CoreRequest.parseUnixSocketUrl(this.options.path); this.options.socketPath = socketPath; this.options.path = path; } // Determine agent based on protocol and keep-alive setting if (!this.options.agent) { // Only use keep-alive agents if explicitly requested if (this.options.keepAlive === true) { this.options.agent = parsedUrl.protocol === 'https:' ? httpsAgent : httpAgent; } else if (this.options.keepAlive === false) { this.options.agent = parsedUrl.protocol === 'https:' ? httpsAgentKeepAliveFalse : httpAgentKeepAliveFalse; } // If keepAlive is undefined, don't set any agent (more fetch-like behavior) } // Determine request module const requestModule = parsedUrl.protocol === 'https:' ? plugins.https : plugins.http; if (!requestModule) { throw new Error(`The request to ${this.url} is missing a viable protocol. Must be http or https`); } // Perform the request const request = requestModule.request(this.options, async (response) => { // Handle hard timeout if (this.options.hardDataCuttingTimeout) { setTimeout(() => { response.destroy(); done.reject(new Error('Request timed out')); }, this.options.hardDataCuttingTimeout); } // Always return the raw stream done.resolve(response); }); // Write request body if (this.options.requestBody) { if (this.options.requestBody instanceof plugins.formData) { this.options.requestBody.pipe(request).on('finish', () => { request.end(); }); } else { // Write body as-is - caller is responsible for serialization const bodyData = typeof this.options.requestBody === 'string' ? this.options.requestBody : this.options.requestBody instanceof Buffer ? this.options.requestBody : JSON.stringify(this.options.requestBody); // Still stringify for backward compatibility request.write(bodyData); request.end(); } } else if (this.requestDataFunc) { this.requestDataFunc(request); } else { request.end(); } // Handle request errors request.on('error', (e) => { console.error(e); request.destroy(); done.reject(e); }); // Get response and handle response errors const response = await done.promise; response.on('error', (err) => { console.error(err); response.destroy(); }); return response; } /** * Static factory method to create and fire a request */ static async create(url, options = {}) { const request = new CoreRequest(url, options); return request.fire(); } } /** * Convenience exports for backward compatibility */ export const isUnixSocket = CoreRequest.isUnixSocket; export const parseUnixSocketUrl = CoreRequest.parseUnixSocketUrl; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVxdWVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL2NvcmUvcmVxdWVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUN4QyxPQUFPLEtBQUssS0FBSyxNQUFNLFlBQVksQ0FBQztBQUNwQyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRTdDLDJDQUEyQztBQUMzQyxNQUFNLFNBQVMsR0FBRyxJQUFJLE9BQU8sQ0FBQyxjQUFjLENBQUMsU0FBUyxDQUFDO0lBQ3JELFNBQVMsRUFBRSxJQUFJO0lBQ2YsY0FBYyxFQUFFLEVBQUU7SUFDbEIsVUFBVSxFQUFFLEdBQUc7SUFDZixlQUFlLEVBQUUsSUFBSTtDQUN0QixDQUFDLENBQUM7QUFFSCxNQUFNLHVCQUF1QixHQUFHLElBQUksT0FBTyxDQUFDLGNBQWMsQ0FBQyxTQUFTLENBQUM7SUFDbkUsU0FBUyxFQUFFLEtBQUs7Q0FDakIsQ0FBQyxDQUFDO0FBRUgsTUFBTSxVQUFVLEdBQUcsSUFBSSxPQUFPLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQztJQUN2RCxTQUFTLEVBQUUsSUFBSTtJQUNmLGNBQWMsRUFBRSxFQUFFO0lBQ2xCLFVBQVUsRUFBRSxHQUFHO0lBQ2YsZUFBZSxFQUFFLElBQUk7Q0FDdEIsQ0FBQyxDQUFDO0FBRUgsTUFBTSx3QkFBd0IsR0FBRyxJQUFJLE9BQU8sQ0FBQyxjQUFjLENBQUMsVUFBVSxDQUFDO0lBQ3JFLFNBQVMsRUFBRSxLQUFLO0NBQ2pCLENBQUMsQ0FBQztBQUVIOztHQUVHO0FBQ0gsTUFBTSxPQUFPLFdBQVc7SUFDdEI7O09BRUc7SUFDSCxNQUFNLENBQUMsWUFBWSxDQUFDLEdBQVc7UUFDN0IsTUFBTSxTQUFTLEdBQUcsK0JBQStCLENBQUM7UUFDbEQsT0FBTyxTQUFTLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzdCLENBQUM7SUFFRDs7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