# Story 4.1: Real Upload Validation ## Summary Successfully validated real file uploads to Bunny.net storage on October 22, 2025. ## Test Details **Storage Zone:** 5axislaser925 **Region:** DE (Frankfurt) **File:** story-4.1-test.html **Result:** HTTP 201 (Success) **Public URL:** https://5axislaser925.b-cdn.net/story-4.1-test.html ## Key Learnings ### 1. Region-Specific URLs Frankfurt (DE) is the default region and uses a different URL pattern: - **DE:** `https://storage.bunnycdn.com/{zone}/{file}` - **Other regions:** `https://{region}.storage.bunnycdn.com/{zone}/{file}` This was implemented in `BunnyStorageClient._get_storage_url()`. ### 2. Content-Type Requirements Per Bunny.net API documentation: - **Required:** `application/octet-stream` - **NOT** `text/html` or other MIME types - File content must be raw binary (we use `.encode('utf-8')`) ### 3. Success Response Code - Bunny.net returns **HTTP 201** for successful uploads (not 200) - This is documented in their API reference ### 4. Authentication - Uses per-zone `storage_zone_password` via `AccessKey` header - Password is stored in database (`site_deployments.storage_zone_password`) - Set automatically when zones are created via `provision-site` or `sync-sites` - NO API key from `.env` needed for uploads ## Implementation Changes Made 1. **Fixed region URL logic** - DE uses no prefix 2. **Changed default Content-Type** - Now uses `application/octet-stream` 3. **Updated success detection** - Looks for HTTP 201 4. **Added region parameter** - All upload methods now require `zone_region` ## Test Coverage **Unit Tests (5):** - DE region URL generation (with/without case) - LA, NY, SG region URL generation **Integration Tests (13):** - Full upload workflow mocking - Deployment service orchestration - URL generation and logging - Error handling **Real-World Test:** - Actual upload to Bunny.net storage - File accessible via CDN URL - HTTP 201 response confirmed ## Status ✅ **VALIDATED** - Ready for production use