/** * @file HTTPDNS API * @desc https://cf.qiniu.io/pages/viewpage.action?pageId=107316632 */ import type Context from '../utils/context'; import type { AppInfo } from '../common/index'; import Logger from '../log'; import { CacheKeyConfig } from './cache-key'; export type Addr = { /** IP 地址 */ ip: string; /** 域名,用于 Web 端带域名访问 */ host: string; /** HTTP 端口 */ http: number; /** HTTPS 端口 */ https: number; /** HoW Proxy 端口 */ how: number; }; export type Elt = { id: string; /** 节点的访问地址信息 */ addrs: Addr[]; /** * @deprecated 使用 `addrs` 代替 * IP + 端口 */ ips: string[]; /** * @deprecated 使用 `addrs` 代替 * 域名 + 端口,有 hosts 信息表示该节点支持带域名访问 */ hosts?: string[]; /** 权重(hash 环中的副本数) */ replicas: number; /** DTLS Cert fingerprint, TODO: 这个不应该在统一的接口里 */ fingerprint: string; }; export type Group = { elts: Elt[]; /** @deprecated Use `weight` in `rules` instead */ weight: number; }; export type GroupInRule = { /** group 在上边 `groups` 中的下标 */ groupidx: number; /** group 的权重 */ weight: number; /** 使用几个 element 来服务该请求 */ splitn: number; }; export type Rule = { /** 匹配规则(正则表达式字符串) */ pattern: string; /** * 服务比例,匹配 pattern 后使用 groups 进行服务的请求数占总请求数的比例 * 如 `servicerate: 0.9` 表示:满足 `pattern` 的请求,90% 使用该 rule 对应的 groups 来服务,10% 走 falllback 逻辑 */ servicerate: number; /** 用于服务请求的 group 信息 */ groups: GroupInRule[]; }; export type MediaOptimizationConfig = { /** 首开优化的阈值,单位 byte;不超过阈值的部分走原 CDN,超过阈值的部分走 ECDN 节点;`threshold: 0` 表示禁用首开优化逻辑 */ threshold: number; }; export type ECDNResolveResult = { /** * Bucket ID,详见国际站(Sufy)的设计文档 https://doc.weixin.qq.com/doc/w3_ACcAvgbfAGo0nbOeEHGSU6sFB3Z7J?scode=AJwASQdIAAw6atURtRAK4A6gbfAGo * 基于 Bucket 的设计是一个将来的设计,在这一设计落地前,这里 `bucket` 字段的值为空字符串 */ bucket: string; /** 调度组列表 */ groups: Group[]; /** 对请求的服务规则 */ rules: Rule[]; /** 缓存 Key 生成规则 */ cacheKey: CacheKeyConfig; /** (音视频)首开优化配置 */ mediaOptimization: MediaOptimizationConfig; /** TTL,单位秒 */ ttl: number; }; export type NormalResolveResult = { /** IP 列表 */ ips: string[]; /** TTL,单位秒 */ ttl: number; }; /** 标识当前处于不支持(ECDN)区域的结果,详见 https://github.com/qbox/miku/issues/338#issuecomment-1436745013 */ export type NotSupportedAreaResolveResult = { reason: 'NotSupportedArea'; /** TTL,单位秒 */ ttl: number; }; /** 若为 ECDNResolveResult(有 groups)则走 ECDN 逻辑,若为 NormalResolveResult(无 groups)则走普通逻辑,详见 https://cf.qiniu.io/pages/viewpage.action?pageId=107316632 */ export type ResolveResult = ECDNResolveResult | NormalResolveResult | NotSupportedAreaResolveResult; /** 基于 HTTP DNS 接口实现域名 resolve */ export declare function httpResolve(ctx: Context, domain: string, app: AppInfo, logger: Logger): Promise; export declare function isECDNResolveResult(result: ResolveResult): result is ECDNResolveResult; export declare function matchRule(rules: Rule[], url: string): Rule | undefined; export declare function shouldServeWithRule(rule: Rule): boolean;