Skip to content

Commit

Permalink
feat(axios): support experimental ctx.http.url()
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Aug 21, 2023
1 parent d1e090d commit 69a0291
Showing 1 changed file with 47 additions and 1 deletion.
48 changes: 47 additions & 1 deletion packages/axios/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Context } from 'cordis'
import { Agent } from 'agent-base'
import { base64ToArrayBuffer, Dict, pick, trimSlash } from 'cosmokit'
import { arrayBufferToBase64, base64ToArrayBuffer, Dict, pick, trimSlash } from 'cosmokit'
import { ClientRequestArgs } from 'http'
import mimedb from 'mime-db'
import axios, { AxiosRequestConfig, AxiosResponse, Method } from 'axios'
Expand All @@ -18,6 +18,41 @@ declare module 'cordis' {
}
}

/* eslint-disable no-multi-spaces */
const ranges = [
'0.0.0.0/8', // RFC 1122 'this' network
'10.0.0.0/8', // RFC 1918 private space
'100.64.0.0/10', // RFC 6598 Carrier grade nat space
'127.0.0.0/8', // RFC 1122 localhost
'169.254.0.0/16', // RFC 3927 link local
'172.16.0.0/12', // RFC 1918 private space
'192.0.2.0/24', // RFC 5737 TEST-NET-1
'192.88.99.0/24', // RFC 7526 6to4 anycast relay
'192.168.0.0/16', // RFC 1918 private space
'198.18.0.0/15', // RFC 2544 benchmarking
'198.51.100.0/24', // RFC 5737 TEST-NET-2
'203.0.113.0/24', // RFC 5737 TEST-NET-3
'224.0.0.0/4', // multicast
'240.0.0.0/4', // reserved
]
/* eslint-enable no-multi-spaces */

function addressToNumber(address: string) {
return address.split('.').reduce((a, b) => (a << 8n) + BigInt(b), 0n)
}

function isPrivate(hostname: string) {
if (/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/.test(hostname)) return false
for (const cidr of ranges) {
const [address, length] = cidr.split('/')
const mask = -1n << BigInt(32 - +length)
const value1 = addressToNumber(hostname) & mask
const value2 = addressToNumber(address) & mask
if (value1 === value2) return true
}
return false
}

export interface Quester {
<T = any>(method: Method, url: string, config?: AxiosRequestConfig): Promise<T>
axios<T = any>(config?: AxiosRequestConfig): Promise<AxiosResponse<T>>
Expand Down Expand Up @@ -111,6 +146,17 @@ export class Quester {
}
return { mime, filename: name, data }
}

async url(url: string) {
const { hostname } = new URL(url)
if (!isPrivate(hostname)) return url
const { headers, data } = await this.axios(url, {
method: 'GET',
responseType: 'arraybuffer',
})
const mime = headers['content-type']
return `data:${mime};base64,${arrayBufferToBase64(data)}`
}
}

export namespace Quester {
Expand Down

0 comments on commit 69a0291

Please sign in to comment.