GigHive bee gighive

TUS Protocol Implementation Guide

Overview

This document outlines adding TUS (Tus Resumable Upload) protocol support to the GigHive iOS client for bypassing Cloudflare’s 100MB upload limit.

Rationale (Condensed)

Recommendation

Implement TUS support for Cloudflare compatibility, using a dedicated TUS endpoint (recommended: tusd behind Apache) and keeping the existing upload path as a fallback.

Why this matters

Why it’s feasible in this codebase

Trade-offs / caveats

Note on Cloudflare Tunnel environments

If an environment’s origin is only reachable via Cloudflare Tunnel, a DNS-only upload subdomain does not bypass Cloudflare limits unless the origin is also publicly reachable. In these environments, TUS (or direct-to-object-storage uploads) is the practical approach.

✅ Already Implemented

Updated Context (January 2026)

Cloudflare Tunnel Constraint

The GigHive origin in some environments is only reachable via Cloudflare Tunnel (for example, routing lab.gighive.app to a private IP). In that setup:

Important: TUS Requires a Separate Server Endpoint

The existing /api/uploads.php endpoint expects a single multipart/form-data request (PHP $_FILES). TUS uses multiple requests (typically POST then multiple PATCH requests with application/offset+octet-stream). Therefore:

Current Behavior (Before TUS Cutover):

See: UPLOAD_OPTIONS.md for detailed analysis

Integration Points Validation

Existing Flow Compatibility

  1. UploadPayload: ✅ No changes needed - same structure
  2. Progress Callbacks: ✅ Same signature (Int64, Int64) -> Void
  3. Error Handling: ✅ Same async/await pattern
  4. Authentication: ✅ Basic auth preserved
  5. Server Endpoint: ⚠️ Requires a dedicated TUS endpoint (not /api/uploads.php)
  6. Finalize Step: ⚠️ Required - after TUS completes, the client must call a finalize endpoint so the server can move/register the file into the existing /audio//video locations and write DB metadata

Why tusd

tusd is the reference TUS server implementation and is available as a Docker image. Running it as a sidecar keeps the upload logic out of the PHP endpoint and provides well-tested resumable upload semantics.

Proposed Routing

Routing invariant (important)

If you see 200 OK with a body like “Welcome to tusd” when creating an upload, you are likely hitting tusd’s welcome endpoint instead of its TUS handler (/files/).

Ansible variables required for TUS

The Ansible playbooks (including post_build_checks) assume the TUS-related variables are defined for the inventory/group being deployed (for example under ansible/inventories/group_vars/<group>/<group>.yml). Key variables include:

ModSecurity Note

Current ModSecurity configuration enforces multipart/form-data for /api/uploads.php and /api/media-files. TUS requests are not multipart. To avoid conflicts:

Operational verification (quick checks)

Direct tusd (from inside the Apache container)

Through Apache (external URL path)

UI Integration

Implementation Checklist

High Priority Tasks

Success Metrics for Week 1

Pass/Fail Criteria

Technical Details

File Size Threshold Logic

// Hard cutover: use TUS protocol for all files
return try await uploadWithTUS(payload: payload, progress: progress)

Key Differences

Method HTTP Requests Use Case Cloudflare Compatible
uploadWithTUS() Multiple PATCH All uploads ✅ Yes
uploadWithMultipartInputStream() 1 POST Legacy fallback only ✅ Yes
Old upload() method 1 POST (loads to memory) Deprecated ⚠️

TUS Configuration

Ready for Implementation (When Needed)

Next Steps


Related Documentation: