function shouldChaos() { return Math.random() < 0.13; // 13% chaos for R2 } function getChaoticR2Response() { const chaos = Math.random(); if (chaos < 0.2) { // Access denied return new Response( 'AccessDeniedAccess Denied', { status: 403, headers: { 'Content-Type': 'application/xml' } } ); } else if (chaos < 0.4) { // Object not found return new Response( 'NoSuchKey', { status: 404, headers: { 'Content-Type': 'application/xml' } } ); } else if (chaos < 0.6) { // Bandwidth limit exceeded return new Response('Rate limit exceeded', { status: 429 }); } else if (chaos < 0.8) { // Corrupted metadata return new Response('corrupted object content', { headers: { 'Content-Type': 'text/plain', 'CF-R2-Metadata-Size': 'not-a-number', // Invalid metadata ETag: 'invalid-etag-format', }, }); } else { // Wrong content type but valid data return new Response(JSON.stringify({ not: 'xml', but: 'json' }), { headers: { 'Content-Type': 'application/xml' }, // Lying about content type }); } } export default { async fetch(request, env, ctx) { // Random chaos injection if (shouldChaos()) { return getChaoticR2Response(); } const { pathname } = new URL(request.url); const method = request.method; if (method === 'GET' && pathname !== '/') { // GET object return new Response('test-object-content', { headers: { 'Content-Type': 'text/plain', 'CF-R2-Metadata-Size': '18', }, }); } else if (method === 'PUT') { // PUT object return new Response( JSON.stringify({ etag: 'mock-etag-' + Math.random().toString(36).substr(2, 9), }), { headers: { 'Content-Type': 'application/json' }, } ); } else if (method === 'GET' && pathname === '/') { // LIST objects (sometimes return inconsistent results) const objects = [{ key: 'test-object', metadata: { size: 18 } }]; if (Math.random() < 0.1) { // Sometimes add random objects to list objects.push({ key: 'mystery-object', metadata: { size: Math.floor(Math.random() * 1000) }, }); } return new Response( JSON.stringify({ keys: objects, is_truncated: Math.random() < 0.05, // Sometimes claim truncation }), { headers: { 'Content-Type': 'application/json' }, } ); } return new Response('R2 mock ready', { status: 200 }); }, };