Hi guys , have a good time.
What is the problem? :
I’m using Cloudflare R2 Storage but have 2 problem :
1. Download files doesn’t support " Resume Capability " .
2. Files download with only 1 connection.
What I tried? :*
I’ve used samples in github public worker
and CF demo worker
of Cloudflare but problem not resolved
https://github.com/cmackenzie1/r2-public-worker
https://developers.cloudflare.com/r2/examples/demo-worker/
Sample :
File/url for testing , hosted on R2 : https://w1.antenha.com/debian-502a-i386-netinst.iso
What worker is using? :
This demo that found on Cloudflare website have a range parser
but it seems doesn’t work.
interface Env {
MY_BUCKET: R2Bucket
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const url = new URL(request.url)
const objectName = url.pathname.slice(1)
console.log(`${request.method} object ${objectName}: ${request.url}`)
if (request.method === 'GET' || request.method === 'HEAD') {
if (request.method === 'GET') {
const range = parseRange(request.headers.get('range'))
const object = await env.MY_BUCKET.get(objectName, {
range,
onlyIf: request.headers,
})
if (object === null) {
return objectNotFound(objectName)
}
const headers = new Headers()
object.writeHttpMetadata(headers)
headers.set('etag', object.httpEtag)
const status = object.body ? (range ? 206 : 200) : 304
return new Response(object.body, {
headers,
status
})
}
const object = await env.MY_BUCKET.head(objectName)
if (object === null) {
return objectNotFound(objectName)
}
const headers = new Headers()
object.writeHttpMetadata(headers)
headers.set('etag', object.httpEtag)
return new Response(null, {
headers,
})
}
return new Response(`Unsupported method`, {
status: 400
})
}
}
function parseRange(encoded: string | null): undefined | { offset: number, length: number } {
if (encoded === null) {
return
}
const parts = encoded.split("bytes=")[1]?.split("-") ?? []
if (parts.length !== 2) {
throw new Error('Not supported to skip specifying the beginning/ending byte at this time')
}
return {
offset: Number(parts[0]),
length: Number(parts[1]) + 1 - Number(parts[0]),
}
}
function objectNotFound(objectName: string): Response {
return new Response(`<html><body>R2 object "<b>${objectName}</b>" not found</body></html>`, {
status: 404,
headers: {
'content-type': 'text/html; charset=UTF-8'
}
})
}