basant307/AI_Governance_Project
048
1import { Agent } from 'http'2import { RequestOptions, Agent as HttpsAgent } from 'https'3import { Logger } from '@open-draft/logger'4 5const logger = new Logger('utils getUrlByRequestOptions')6 7// Request instance constructed by the "request" library8// has a "self" property that has a "uri" field. This is9// reproducible by performing a "XMLHttpRequest" request in JSDOM.10export interface RequestSelf {11 uri?: URL12}13 14export type ResolvedRequestOptions = RequestOptions & RequestSelf15 16export const DEFAULT_PATH = '/'17const DEFAULT_PROTOCOL = 'http:'18const DEFAULT_HOSTNAME = 'localhost'19const SSL_PORT = 44320 21function getAgent(22 options: ResolvedRequestOptions23): Agent | HttpsAgent | undefined {24 return options.agent instanceof Agent ? options.agent : undefined25}26 27function getProtocolByRequestOptions(options: ResolvedRequestOptions): string {28 if (options.protocol) {29 return options.protocol30 }31 32 const agent = getAgent(options)33 const agentProtocol = (agent as RequestOptions)?.protocol34 35 if (agentProtocol) {36 return agentProtocol37 }38 39 const port = getPortByRequestOptions(options)40 const isSecureRequest = options.cert || port === SSL_PORT41 42 return isSecureRequest ? 'https:' : options.uri?.protocol || DEFAULT_PROTOCOL43}44 45function getPortByRequestOptions(46 options: ResolvedRequestOptions47): number | undefined {48 // Use the explicitly provided port.49 if (options.port) {50 return Number(options.port)51 }52 53 // Otherwise, try to resolve port from the agent.54 const agent = getAgent(options)55 56 if ((agent as HttpsAgent)?.options.port) {57 return Number((agent as HttpsAgent).options.port)58 }59 60 if ((agent as RequestOptions)?.defaultPort) {61 return Number((agent as RequestOptions).defaultPort)62 }63 64 // Lastly, return undefined indicating that the port65 // must inferred from the protocol. Do not infer it here.66 return undefined67}68 69interface RequestAuth {70 username: string71 password: string72}73 74function getAuthByRequestOptions(75 options: ResolvedRequestOptions76): RequestAuth | undefined {77 if (options.auth) {78 const [username, password] = options.auth.split(':')79 return { username, password }80 }81}82 83/**84 * Returns true if host looks like an IPv6 address without surrounding brackets85 * It assumes any host containing `:` is definitely not IPv4 and probably IPv6,86 * but note that this could include invalid IPv6 addresses as well.87 */88function isRawIPv6Address(host: string): boolean {89 return host.includes(':') && !host.startsWith('[') && !host.endsWith(']')90}91 92function getHostname(options: ResolvedRequestOptions): string | undefined {93 let host = options.hostname || options.host94 95 if (host) {96 if (isRawIPv6Address(host)) {97 host = `[${host}]`98 }99 100 // Check the presence of the port, and if it's present,101 // remove it from the host, returning a hostname.102 return new URL(`http://${host}`).hostname103 }104 105 return DEFAULT_HOSTNAME106}107 108/**109 * Creates a `URL` instance from a given `RequestOptions` object.110 */111export function getUrlByRequestOptions(options: ResolvedRequestOptions): URL {112 logger.info('request options', options)113 114 if (options.uri) {115 logger.info(116 'constructing url from explicitly provided "options.uri": %s',117 options.uri118 )119 return new URL(options.uri.href)120 }121 122 logger.info('figuring out url from request options...')123 124 const protocol = getProtocolByRequestOptions(options)125 logger.info('protocol', protocol)126 127 const port = getPortByRequestOptions(options)128 logger.info('port', port)129 130 const hostname = getHostname(options)131 logger.info('hostname', hostname)132 133 const path = options.path || DEFAULT_PATH134 logger.info('path', path)135 136 const credentials = getAuthByRequestOptions(options)137 logger.info('credentials', credentials)138 139 const authString = credentials140 ? `${credentials.username}:${credentials.password}@`141 : ''142 logger.info('auth string:', authString)143 144 const portString = typeof port !== 'undefined' ? `:${port}` : ''145 const url = new URL(`${protocol}//${hostname}${portString}${path}`)146 url.username = credentials?.username || ''147 url.password = credentials?.password || ''148 149 logger.info('created url:', url)150 151 return url152}153 