installer-rp: decode data: URL images instead of crashing
사진 URL 에 data: URI 가 들어오면 http/https 만 처리하는 다운로더가 'Protocol "data:" not supported' 로 설치 전체를 중단시키던 문제 수정. data: URL 은 이미지 바이트를 직접 품고 있으므로 base64/percent-encoding 을 디코드해 Buffer 로 바로 반환한다. 잘못된 형식은 명확한 메시지로 거절.
This commit is contained in:
@@ -63,13 +63,36 @@ function fetchBuffer(url: string, redirects = 0): Promise<Buffer> {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* data: URL 이면 그 안에 들어 있는 바이트를 바로 Buffer 로 디코드한다.
|
||||
* data: URL 은 이미지 데이터 자체를 품고 있어 네트워크 요청이 필요 없으며,
|
||||
* http/https 만 다루는 fetchBuffer 에 넘기면 `Protocol "data:" not supported`
|
||||
* 로 터지므로 여기서 가로챈다. data: URL 이 아니면 null.
|
||||
*/
|
||||
function decodeDataUrl(url: string): Buffer | null {
|
||||
if (!/^data:/i.test(url)) return null
|
||||
const comma = url.indexOf(',')
|
||||
if (comma < 0) throw new Error(t('errors.imageDataUrlInvalid'))
|
||||
const meta = url.slice(5, comma)
|
||||
const data = url.slice(comma + 1)
|
||||
// `;base64` 가 있으면 base64, 없으면 percent-encoding 된 텍스트.
|
||||
const buf = /;base64/i.test(meta)
|
||||
? Buffer.from(data, 'base64')
|
||||
: Buffer.from(decodeURIComponent(data), 'utf8')
|
||||
if (buf.length === 0) throw new Error(t('errors.imageDataUrlInvalid'))
|
||||
return buf
|
||||
}
|
||||
|
||||
/**
|
||||
* 이미지 URL 을 다운로드해 Buffer 로 돌려준다.
|
||||
* - data: URL 이면 내장 바이트를 바로 디코드 (네트워크 없음).
|
||||
* - 유튜브 영상 URL 이면 `i.ytimg.com/vi/<id>/maxresdefault.jpg` 1차 →
|
||||
* 실패하면 `hqdefault.jpg` 로 폴백.
|
||||
* - 그 외 URL 은 HTTP GET 으로 그대로 받음.
|
||||
*/
|
||||
export async function downloadImage(rawUrl: string): Promise<Buffer> {
|
||||
const dataBuf = decodeDataUrl(rawUrl)
|
||||
if (dataBuf) return dataBuf
|
||||
const ytId = ytIdFromUrl(rawUrl)
|
||||
if (ytId) {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user