Cloudflare R2 downloading files with resume capability problem

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'
    }
  })
}


I use this:

I haven’t looked at the code much but interrupting/resuming downloads with wget works fine

1 Like

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.