Sylvain Filoni
update gradio client
9ada4bc
import { Agent } from 'http'
import { RequestOptions, Agent as HttpsAgent } from 'https'
import { Logger } from '@open-draft/logger'
const logger = new Logger('utils getUrlByRequestOptions')
// Request instance constructed by the "request" library
// has a "self" property that has a "uri" field. This is
// reproducible by performing a "XMLHttpRequest" request in JSDOM.
export interface RequestSelf {
uri?: URL
}
export type ResolvedRequestOptions = RequestOptions & RequestSelf
export const DEFAULT_PATH = '/'
const DEFAULT_PROTOCOL = 'http:'
const DEFAULT_HOSTNAME = 'localhost'
const SSL_PORT = 443
function getAgent(
options: ResolvedRequestOptions
): Agent | HttpsAgent | undefined {
return options.agent instanceof Agent ? options.agent : undefined
}
function getProtocolByRequestOptions(options: ResolvedRequestOptions): string {
if (options.protocol) {
return options.protocol
}
const agent = getAgent(options)
const agentProtocol = (agent as RequestOptions)?.protocol
if (agentProtocol) {
return agentProtocol
}
const port = getPortByRequestOptions(options)
const isSecureRequest = options.cert || port === SSL_PORT
return isSecureRequest ? 'https:' : options.uri?.protocol || DEFAULT_PROTOCOL
}
function getPortByRequestOptions(
options: ResolvedRequestOptions
): number | undefined {
// Use the explicitly provided port.
if (options.port) {
return Number(options.port)
}
// Otherwise, try to resolve port from the agent.
const agent = getAgent(options)
if ((agent as HttpsAgent)?.options.port) {
return Number((agent as HttpsAgent).options.port)
}
if ((agent as RequestOptions)?.defaultPort) {
return Number((agent as RequestOptions).defaultPort)
}
// Lastly, return undefined indicating that the port
// must inferred from the protocol. Do not infer it here.
return undefined
}
interface RequestAuth {
username: string
password: string
}
function getAuthByRequestOptions(
options: ResolvedRequestOptions
): RequestAuth | undefined {
if (options.auth) {
const [username, password] = options.auth.split(':')
return { username, password }
}
}
/**
* Returns true if host looks like an IPv6 address without surrounding brackets
* It assumes any host containing `:` is definitely not IPv4 and probably IPv6,
* but note that this could include invalid IPv6 addresses as well.
*/
function isRawIPv6Address(host: string): boolean {
return host.includes(':') && !host.startsWith('[') && !host.endsWith(']')
}
function getHostname(options: ResolvedRequestOptions): string | undefined {
let host = options.hostname || options.host
if (host) {
if (isRawIPv6Address(host)) {
host = `[${host}]`
}
// Check the presence of the port, and if it's present,
// remove it from the host, returning a hostname.
return new URL(`http://${host}`).hostname
}
return DEFAULT_HOSTNAME
}
/**
* Creates a `URL` instance from a given `RequestOptions` object.
*/
export function getUrlByRequestOptions(options: ResolvedRequestOptions): URL {
logger.info('request options', options)
if (options.uri) {
logger.info(
'constructing url from explicitly provided "options.uri": %s',
options.uri
)
return new URL(options.uri.href)
}
logger.info('figuring out url from request options...')
const protocol = getProtocolByRequestOptions(options)
logger.info('protocol', protocol)
const port = getPortByRequestOptions(options)
logger.info('port', port)
const hostname = getHostname(options)
logger.info('hostname', hostname)
const path = options.path || DEFAULT_PATH
logger.info('path', path)
const credentials = getAuthByRequestOptions(options)
logger.info('credentials', credentials)
const authString = credentials
? `${credentials.username}:${credentials.password}@`
: ''
logger.info('auth string:', authString)
const portString = typeof port !== 'undefined' ? `:${port}` : ''
const url = new URL(`${protocol}//${hostname}${portString}${path}`)
url.username = credentials?.username || ''
url.password = credentials?.password || ''
logger.info('created url:', url)
return url
}