Skip to content

Commit

Permalink
feat(axios): add http.isPrivate(), fix #139
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Aug 28, 2023
1 parent 84930aa commit 045c563
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 19 deletions.
32 changes: 18 additions & 14 deletions adapters/discord/src/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,30 +110,34 @@ export class DiscordMessageEncoder extends MessageEncoder<DiscordBot> {
return this.post({ ...addition, content: attrs.url })
}

const sendDownload = () => this.sendEmbed(attrs, addition)

if (['file:', 'data:', 'base64:'].some((prefix) => attrs.url.startsWith(prefix))) {
return await sendDownload()
if (this.bot.http.isPrivate(attrs.url)) {
return await this.sendEmbed(attrs, addition)
}

const mode = attrs.mode as DiscordMessageEncoder.HandleExternalAsset || handleExternalAsset
if (mode === 'download' || handleMixedContent === 'attach' && addition.content || type === 'file') {
return sendDownload()
return this.sendEmbed(attrs, addition)
} else if (mode === 'direct') {
return sendDirect()
}

// auto mode
return await this.bot.ctx.http.head(attrs.url, {
if (await this.checkMediaType(attrs.url, type)) {
return sendDirect()
} else {
return this.sendEmbed(attrs, addition)
}
}

checkMediaType(url: string, type: string) {
if (url.startsWith('https://cdn.discordapp.com/')) return true
return this.bot.ctx.http.head(url, {
headers: { accept: type + '/*' },
timeout: +attrs.timeout || undefined,
}).then((headers) => {
if (headers['content-type'].startsWith(type)) {
return sendDirect()
} else {
return sendDownload()
}
}, sendDownload)
timeout: 1000,
}).then(
(headers) => headers['content-type'].startsWith(type),
() => false,
)
}

async ensureWebhook() {
Expand Down
2 changes: 1 addition & 1 deletion adapters/kook/src/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export class KookMessageEncoder extends MessageEncoder<KookBot> {
}

private async transformUrl({ type, attrs }: h) {
if (['file:', 'base64:', 'data:'].some(protocol => attrs.url.startsWith(protocol))) {
if (this.bot.http.isPrivate(attrs.url)) {
const payload = new FormData()
const result = await this.bot.ctx.http.file(attrs.url, attrs)
payload.append('file', Buffer.from(result.data), {
Expand Down
13 changes: 9 additions & 4 deletions packages/axios/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ function addressToNumber(address: string) {
}

function isPrivate(hostname: string) {
if (/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/.test(hostname)) return false
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)
Expand Down Expand Up @@ -147,9 +147,14 @@ export class Quester {
return { mime, filename: name, data }
}

async url(url: string) {
const { hostname } = new URL(url)
if (!isPrivate(hostname)) return url
isPrivate(url: string) {
const { hostname, protocol } = new URL(url)
if (protocol !== 'http:' && protocol !== 'https:') return true
return isPrivate(hostname)
}

async toPublic(url: string) {
if (!this.isPrivate(url)) return url
const { headers, data } = await this.axios(url, {
method: 'GET',
responseType: 'arraybuffer',
Expand Down

0 comments on commit 045c563

Please sign in to comment.