$method, CURLOPT_POSTFIELDS => $body, CURLOPT_HTTPHEADER => $headers, CURLOPT_RETURNTRANSFER => true, CURLOPT_FOLLOWLOCATION => false, CURLOPT_TIMEOUT => 300, CURLOPT_HEADERFUNCTION => function ($curl, string $line) use (&$etag): int { if (stripos($line, 'etag:') === 0) $etag = trim(substr($line, 5), " \t\r\n\""); return strlen($line); }, ]); $data = curl_exec($curl); $status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE); $error = curl_error($curl); curl_close($curl); if ($data === false || $status < 200 || $status >= 300) { throw new RuntimeException("HTTP $status: " . ($error ?: $data)); } return [$data, $etag]; } function api(string $route, array $body): array { global $origin, $key; [$data] = request($origin . '/api/v1' . $route, 'POST', json_encode($body, JSON_THROW_ON_ERROR), ['Authorization: Bearer ' . $key, 'Content-Type: application/json']); return json_decode($data, true, 512, JSON_THROW_ON_ERROR); } $size = filesize($path); $file = fopen($path, 'rb'); if ($file === false) throw new RuntimeException('Cannot open file'); try { $plan = api('/uploads/init', ['filename' => basename($path), 'sizeBytes' => $size]); fwrite(STDERR, 'Upload ID: ' . $plan['fileId'] . PHP_EOL); if ($plan['partSize'] < 1 || $plan['partSize'] > 64 * 1024 * 1024) throw new RuntimeException('Unexpected part size'); $parts = []; for ($number = 1; $number <= $plan['partCount']; $number++) { $length = min($plan['partSize'], $size - ($number - 1) * $plan['partSize']); $bytes = stream_get_contents($file, $length); if ($bytes === false || strlen($bytes) !== $length) throw new RuntimeException('File changed during upload'); $address = $plan['single'] ? $plan['uploadUrl'] : api('/uploads/parts', ['fileId' => $plan['fileId'], 'from' => $number, 'count' => 1])['parts'][0]['url']; $headers = ['Content-Type: application/octet-stream']; if ($plan['strategy'] === 'proxy' && str_starts_with($address, '/api/v1/uploads/')) { $url = $origin . $address; $headers[] = 'Authorization: Bearer ' . $key; } elseif ($plan['strategy'] === 'presigned' && parse_url($address, PHP_URL_SCHEME) === 'https') { $url = $address; } else { throw new RuntimeException('Unexpected upload URL or strategy'); } if ($plan['single'] && $plan['strategy'] === 'presigned') $headers[] = 'If-None-Match: *'; [$data, $etag] = request($url, 'PUT', $bytes, $headers); if (!$plan['single']) { if ($plan['strategy'] === 'proxy') $etag = json_decode($data, true, 512, JSON_THROW_ON_ERROR)['etag']; if (!$etag) throw new RuntimeException('Missing part ETag'); $parts[] = ['partNumber' => $number, 'etag' => trim($etag, '"')]; } } $result = api('/uploads/complete', ['fileId' => $plan['fileId'], 'parts' => $parts]); echo ($result['shareUrl'] ?? json_encode($result, JSON_THROW_ON_ERROR)) . PHP_EOL; } finally { fclose($file); }