📁 URL → Google Drive Uploader

Cloudflare Workers-based chunked file transfer system documentation

Cloudflare Workers Google Drive API v3 Resumable Upload
📌 System Overview

What is this system?

This is a URL-to-Google Drive file transfer system built entirely on Cloudflare Workers. A user provides a direct download link and Google OAuth credentials. The system then transfers the file from the source server directly to Google Drive in 4 MiB chunks — without the file ever passing through the user's browser or home internet.

🧩 Key Components

  • Backend Worker (Chunk Worker) — Downloads and uploads one chunk per invocation
  • Frontend Worker (Setup Worker + UI) — Serves the frontend, handles OAuth, creates upload session
  • Browser (Client-Side JS) — Orchestrates the chunk loop, calling Backend Worker per chunk
The actual file data flows Source Server → Cloudflare Worker → Google Drive. Your home internet only sends/receives tiny JSON control messages (~few KB each).
🏗️ Architecture

System Design — Hybrid Model

This system uses a hybrid architecture: the heavy data transfer is fully server-side (inside Cloudflare Workers), but the orchestration/loop control is browser-side (client JavaScript).

File Data Path (4 MiB chunks)

Each chunk follows this path — your browser is NOT in this path:

🌐 Source Server
⚡ Backend Worker Worker
📁 Google Drive

Control Signal Path (JSON messages)

The browser only sends instructions and receives status updates:

🖥️ Browser
⚡ Backend Worker Worker
🖥️ Browser

Payload: ~200 bytes JSON request → ~30 bytes JSON response per chunk

⚠️
The two Workers are not connected via Cloudflare Service Bindings. The browser acts as the bridge between them.
📜 Script Breakdown

⚡ Backend Worker — Chunk Worker

  • Receives chunk instructions via POST
  • Downloads 4 MiB chunk from source using Range request
  • Uploads that chunk to Google Drive via resumable upload PUT
  • Returns JSON status: success / complete / error
  • Handles CORS preflight for cross-origin requests
  • Fully stateless — each invocation is independent
  • Does NOT serve any UI

🖥️ Frontend Worker — Setup + UI Worker

  • Serves the HTML/CSS/JS frontend on GET requests
  • Accepts source URL + Google OAuth credentials
  • Sends HEAD request to source to get file size & name
  • Exchanges refresh token for access token via Google OAuth
  • Creates Google Drive resumable upload session
  • Returns setup data (sessionUrl, accessToken, etc.)
  • Does NOT upload any file data

Script Roles Summary

ResponsibilityBackend WorkerFrontend Worker
Serve UI / HTML Page
Collect User Input
Get File Metadata (HEAD)
Google OAuth Token Exchange
Create Resumable Upload Session
Download File Chunk
Upload File Chunk to Drive
CORS Handling

Backend Worker — Request Body Parameters

FieldTypeDescription
sourceUrlStringDirect download URL of the source file
sessionUrlStringGoogle Drive resumable upload session URL
accessTokenStringGoogle OAuth2 Bearer access token
contentLengthNumberTotal file size in bytes
chunkNumberNumber1-based chunk index to process

Backend Worker — Response Status Codes

Google HTTP StatusMeaningWorker Response
308Chunk accepted, more needed{ status: "success" }
200 / 201Final chunk, file complete{ status: "complete" }
OtherError occurred{ status: "error", code: ... }
🔄 Upload Flow — Step by Step
1

User Submits Form

User enters source URL, Google Client ID, Client Secret, and Refresh Token in the HTML form served by Frontend Worker.

2

Browser → Frontend Worker: POST /api/setup

Browser sends credentials to Frontend Worker. Frontend Worker performs a HEAD request on the source URL to get file size, MIME type, and filename.

3

Frontend Worker → Google OAuth

Frontend Worker exchanges the refresh token for a fresh access token via Google's OAuth2 token endpoint.

4

Frontend Worker → Google Drive API

Frontend Worker creates a resumable upload session with Google Drive and receives a unique session URL.

5

Frontend Worker → Browser: Setup Response

Frontend Worker returns all setup data to the browser: sourceUrl, filename, contentLength, accessToken, sessionUrl.

6

Browser → Backend Worker: Chunk Loop Begins

Browser calculates total chunks = ceil(contentLength / 4 MiB). Then loops from chunk 1 to N, sending a POST to Backend Worker for each chunk sequentially.

7

Backend Worker: Download → Upload (per chunk)

Backend Worker downloads the specific 4 MiB chunk from the source server using an HTTP Range request, then uploads it to Google Drive via PUT with Content-Range header.

8

Upload Complete

When the final chunk returns status "complete", the browser shows a success message. The file is now in Google Drive.

🧱 Chunking & Invocations

Chunk Size

Every chunk is exactly 4 MiB (4,194,304 bytes) except the last chunk, which may be smaller if the file size is not perfectly divisible by 4 MiB.

Byte Range Calculation

Chunk #Start ByteEnd Byte
104,194,303
24,194,3048,388,607
38,388,60812,582,911
N (last)(N-1) × 4,194,304contentLength - 1

One Chunk = One Invocation

Every single chunk gets its own separate, independent Worker invocation. Chunks do NOT share a single long-running invocation. This is by design to stay within Cloudflare Workers' per-request CPU and memory limits.

Example: A 20 MiB file = 5 chunks = 5 separate Backend Worker invocations

Chunk 1Invocation #1
Chunk 2Invocation #2
Chunk 3Invocation #3
Chunk 4Invocation #4
Chunk 5Invocation #5

Purely Sequential — No Parallelism

The upload is 100% sequential. The browser uses await inside the loop, meaning:

  • Chunk 1 is downloaded and uploaded completely
  • Only then chunk 2 starts
  • Only then chunk 3 starts
  • And so on... No overlap, no parallelism
Upload Speed

What determines the upload speed?

The actual file data never touches your home internet. Upload speed depends entirely on server-side factors:

🌐
Source Server Outbound Speed

How fast the source server can serve the file chunks

Cloudflare Worker Speed

How fast Cloudflare can download from source and upload to Google

📁
Google Drive Inbound Speed

How fast Google Drive accepts the uploaded chunks

🔗
Network Routing & Latency

Latency between Cloudflare ↔ Source and Cloudflare ↔ Google

Your home internet upload/download speed does NOT affect the file transfer speed. Your browser only sends/receives tiny JSON control messages (~200 bytes per chunk request).
💡
However, your home internet must remain connected and stable enough to keep triggering new chunk requests. If your connection drops, the loop stops.
⚠️ Limitations & Important Notes

🖥️ Browser Must Stay Open

Since the chunk loop runs in client-side JavaScript, the browser tab must remain open until the entire upload finishes. Closing or refreshing the tab will stop the upload immediately. This is NOT a fully background/server-side system.

🔄 No Resume on Failure

If any chunk fails, the upload stops with an error. There is no retry logic or checkpoint system. The entire upload must be restarted from scratch.

🔑 Access Token Expiry

Google OAuth access tokens expire after ~1 hour. For very large files with many chunks, the token may expire mid-upload, causing a failure. There is no automatic token refresh during the upload loop.

🔐 Security Consideration

OAuth credentials (Client ID, Client Secret, Refresh Token) are sent to Frontend Worker, and the Access Token is sent to Backend Worker. While all communication uses HTTPS, these credentials are exposed in browser memory and network requests.

📡 Source Server Requirements

The source server must support HTTP Range requests (partial content downloads) for chunked downloading to work. It must also return proper Content-Length headers on HEAD requests.

📏 Cloudflare Worker Limits

Each Worker invocation must complete within Cloudflare's CPU time and memory limits. With a 4 MiB chunk size, each invocation processes at most 4 MiB of data, which stays well within standard Worker limits.

FAQ

Does the file pass through my browser?

No. The file data moves directly from Source Server → Cloudflare Worker → Google Drive. Your browser only sends small JSON instructions and receives small JSON status responses.

Does my home internet speed affect upload speed?

No. The upload speed depends entirely on the source server speed, Cloudflare's network speed, and Google Drive's acceptance speed. Your home internet only carries tiny control messages.

Can I close my browser during upload?

No. The browser runs the chunk loop. Closing it stops the upload immediately. The currently processing chunk might finish, but no new chunks will be requested.

Are the two Workers connected via Service Binding?

No. Both Workers are in the same Cloudflare account but are not connected via any binding. The browser acts as the bridge — it calls Frontend Worker for setup and Backend Worker for each chunk upload.

Is uploading parallel or sequential?

Purely sequential. One chunk is fully downloaded and uploaded before the next one begins. There is zero parallelism.

What happens if a chunk fails?

The upload stops. An error message is displayed with the failed chunk number. There is no automatic retry. You must restart the entire process.

How many Worker invocations does a file require?

1 Frontend Worker invocation (setup) + N Backend Worker invocations (one per chunk) + possible CORS preflight invocations. For a 100 MiB file: 1 + 25 = at least 26 invocations.