removed extra HEAD request for filesize with shoddy af code, updated compat date

This commit is contained in:
uh wot 2022-04-13 22:58:56 +02:00
parent 80c9ddf1bb
commit 7b00c3560d
Signed by: uhwot
GPG Key ID: CB2454984587B781
4 changed files with 77 additions and 61 deletions

4
dist/worker.js vendored

File diff suppressed because one or more lines are too long

130
index.js
View File

@ -189,13 +189,16 @@ async function track(id, format, tagging, range_header) {
return new Response('Format unavailable', { status: 403, headers: { 'content-type': 'text/plain' } }) return new Response('Format unavailable', { status: 403, headers: { 'content-type': 'text/plain' } })
} }
let range_start = null let range_req = false
let range_end = null let range_start = 0
let range_end = NaN
if (range_header !== null) { if (range_header !== null) {
const range_match = range_header.match(/^bytes=(\d+)-(\d*)/) const range_match = range_header.match(/^bytes=(\d*)-(\d*)/)
if (range_match !== null) { if (range_match !== null) {
range_start = parseInt(range_match[1]) range_start = parseInt(range_match[1])
range_end = parseInt(range_match[2]) range_end = parseInt(range_match[2])
range_req = true
} }
} }
@ -252,7 +255,7 @@ async function track(id, format, tagging, range_header) {
let title = json.SNG_TITLE let title = json.SNG_TITLE
if (json.VERSION) title += ` ${json.VERSION}` if (json.VERSION) title += ` ${json.VERSION}`
let init = {} let init = { method: 'GET', headers: {} }
let resp_init = { let resp_init = {
status: 200, status: 200,
headers: { headers: {
@ -262,20 +265,8 @@ async function track(id, format, tagging, range_header) {
} }
} }
// filesize from the API isn't always the actual filesize,
// so we get it with a HEAD request instead
// example: https://www.deezer.com/track/7703895
let track_size
let track_head = await fetch(track_url, {method: 'HEAD'})
if (track_head.status !== 200) {
return new Response("Couldn't get track stream", { status: 403, headers: { 'content-type': 'text/plain' } })
} else {
track_size = parseInt(track_head.headers.get('content-length'))
}
let resp_size = track_size
let id3_buffer let id3_buffer
let id3_len = 0
if (tagging) { if (tagging) {
let id3 = new ID3Writer(Buffer.alloc(0)); let id3 = new ID3Writer(Buffer.alloc(0));
id3.padding = 0 id3.padding = 0
@ -326,75 +317,100 @@ async function track(id, format, tagging, range_header) {
id3.addTag(); id3.addTag();
id3_buffer = id3.arrayBuffer id3_buffer = id3.arrayBuffer
resp_size += id3_buffer.byteLength id3_len = id3_buffer.byteLength
} }
let skip_id3 = false let skip_id3 = false
let skip_stream = false let skip_stream = false
let fixed_range_start = 0 let trk_range_start = 0
let fixed_range_end = track_size let trk_range_end = NaN
let bytes_remove_start = 0 let bytes_remove_start = 0
let bytes_remove_end = 0 let bytes_remove_end = 0
if (range_start !== null) { if (range_req) {
if (isNaN(range_end)) { if (isNaN(range_start)) {
range_end = resp_size range_start = 0
} else { }
if (!isNaN(range_end)) {
range_end++ range_end++
} }
if (range_start < 0 || range_start > resp_size || range_end < range_start || range_end > resp_size) { if (range_start < 0 || range_end < range_start) {
return new Response('Range invalid', { status: 416, headers: { 'content-type': 'text/plain' } }) return new Response('Invalid range', { status: 416, headers: { 'content-type': 'text/plain' } })
} }
let orig_range_start = range_start trk_range_start = range_start
let orig_range_end = range_end trk_range_end = range_end
if (tagging) { if (tagging) {
let id3_len = id3_buffer.byteLength if (trk_range_start < id3_len) {
if (range_start < id3_len) {
let bytes_remove_id3_end = undefined let bytes_remove_id3_end = undefined
if (range_end < id3_len) { if (trk_range_end < id3_len && !isNaN(trk_range_end)) {
bytes_remove_id3_end = id3_len - (id3_len - range_end) bytes_remove_id3_end = id3_len - (id3_len - trk_range_end)
skip_stream = true skip_stream = true
} else { } else {
range_end -= id3_len trk_range_end -= id3_len
range_start = 0
} }
id3_buffer = id3_buffer.slice(range_start, bytes_remove_id3_end) id3_buffer = id3_buffer.slice(trk_range_start, bytes_remove_id3_end)
trk_range_start = 0
} else { } else {
skip_id3 = true skip_id3 = true
range_start -= id3_len trk_range_start -= id3_len
range_end -= id3_len trk_range_end -= id3_len
} }
} }
if (!skip_stream) { if (!skip_stream) {
bytes_remove_start = range_start % 2048 bytes_remove_start = trk_range_start % 2048
bytes_remove_end = 2048 - range_end % 2048 bytes_remove_end = 2048 - trk_range_end % 2048
fixed_range_start = range_start - bytes_remove_start trk_range_start -= bytes_remove_start
fixed_range_end = range_end + bytes_remove_end trk_range_end += bytes_remove_end
if (fixed_range_end >= track_size) {
fixed_range_end = track_size let tmp_trk_range_end = trk_range_end
bytes_remove_end = 0 if (isNaN(tmp_trk_range_end)) {
tmp_trk_range_end = ''
} else {
tmp_trk_range_end--
} }
init = { headers: new Headers({ range: `bytes=${fixed_range_start}-${fixed_range_end - 1}` }) } init.headers.range = `bytes=${trk_range_start}-${tmp_trk_range_end}`
} else {
init.method = 'HEAD'
} }
resp_init.status = 206
resp_init.headers['content-range'] = `bytes ${orig_range_start}-${orig_range_end - 1}/${resp_size}`
resp_size = orig_range_end - orig_range_start
} }
let track let track
if (!skip_stream) { track = await fetch(track_url, init)
track = await fetch(track_url, init) if (![200, 206].includes(track.status)) {
if (![200, 206].includes(track.status)) { if (track.status === 416) {
return new Response("Couldn't get track stream", { status: 403, headers: { 'content-type': 'text/plain' } }) return new Response('Invalid range', { status: 416, headers: { 'content-type': 'text/plain' } })
} }
return new Response("Couldn't get track stream", { status: 403, headers: { 'content-type': 'text/plain' } })
}
let track_size
if (!range_req || skip_stream) {
track_size = parseInt(track.headers.get('content-length'))
} else {
const range_header_match = track.headers.get('content-range').match(/^bytes (\d+)-(\d+)\/(\d+)/)
track_size = parseInt(range_header_match[3])
}
if (isNaN(range_end)) {
range_end = track_size + id3_len
trk_range_end = track_size
}
let resp_size = range_end - range_start
if (range_req) {
if (trk_range_end >= track_size) {
bytes_remove_end = 0
}
resp_init.status = 206
resp_init.headers['content-range'] = `bytes ${range_start}-${range_end - 1}/${track_size + id3_len}`
} }
let { readable, writable } = new FixedLengthStream(resp_size) let { readable, writable } = new FixedLengthStream(resp_size)
@ -412,7 +428,7 @@ async function track(id, format, tagging, range_header) {
const cipher = new wasm.Cipher(String(id)) const cipher = new wasm.Cipher(String(id))
pipeDecryptedStream(writer, track.body, fixed_range_end, cipher, fixed_range_start, bytes_remove_start, bytes_remove_end) pipeDecryptedStream(writer, track.body, trk_range_end, cipher, trk_range_start, bytes_remove_start, bytes_remove_end)
} else { } else {
writer.close() writer.close()
} }
@ -420,9 +436,8 @@ async function track(id, format, tagging, range_header) {
return new Response(readable, resp_init) return new Response(readable, resp_init)
} }
async function pipeDecryptedStream(writer, body, length, cipher, fixed_range_start, bytes_remove_start, bytes_remove_end) { async function pipeDecryptedStream(writer, body, length, cipher, byte_count, bytes_remove_start, bytes_remove_end) {
const reader = body.getReader({ mode: 'byob' }) const reader = body.getReader({ mode: 'byob' })
let byte_count = fixed_range_start
let end = false let end = false
while (!end) { while (!end) {
@ -447,6 +462,7 @@ async function pipeDecryptedStream(writer, body, length, cipher, fixed_range_sta
byte_count += 2048 byte_count += 2048
} }
reader.cancel()
writer.close() writer.close()
} }

View File

@ -12,7 +12,7 @@
"devDependencies": { "devDependencies": {
"@wasm-tool/wasm-pack-plugin": "^1.6.0", "@wasm-tool/wasm-pack-plugin": "^1.6.0",
"html-loader": "^1.3.2", "html-loader": "^1.3.2",
"prettier": "^2.6.1" "prettier": "^2.6.2"
}, },
"dependencies": { "dependencies": {
"browser-id3-writer": "^4.4.0", "browser-id3-writer": "^4.4.0",

View File

@ -6,7 +6,7 @@ workers_dev = true
kv_namespaces = [ kv_namespaces = [
{ binding = "KV", id = "974c0967a84e415daa054bbbcc7f80c6", preview_id = "cfcc6491f3484cbca664913836635113" } { binding = "KV", id = "974c0967a84e415daa054bbbcc7f80c6", preview_id = "cfcc6491f3484cbca664913836635113" }
] ]
compatibility_date = "2022-03-29" compatibility_date = "2022-04-13"
# [secrets] # [secrets]
# ARL # ARL