nostolgagram/api/v1/media/upload.php
2026-06-24 21:39:10 +01:00

76 lines
No EOL
2.6 KiB
PHP

<?php
/**
* Module E1: Media Binary Stream Upload Carrier
* Target Path: htdocs/api/v1/media/upload.php
*/
require_once __DIR__ . '/../../../config.php';
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
http_response_code(405);
die(json_encode(["status" => "fail", "message" => "Method not allowed."]));
}
// Ensure the client application is authenticated
$sessionCookie = $_COOKIE['sessionid'] ?? '';
if (empty($sessionCookie) || strpos($sessionCookie, 'nostolga_sess_') !== 0) {
http_response_code(401);
die(json_encode(["status" => "fail", "message" => "Unauthorized session context."]));
}
// Instagram legacy apps look for a unique upload_id to track the processing pipeline
// If the client didn't supply one, we auto-generate a timestamp token signature
$uploadId = $_POST['upload_id'] ?? (string)floor(microtime(true) * 1000);
// Detect the file upload array element payload keys
$fileKey = isset($_FILES['photo']) ? 'photo' : (isset($_FILES['file']) ? 'file' : null);
if (!$fileKey || $_FILES[$fileKey]['error'] !== UPLOAD_ERR_OK) {
http_response_code(400);
die(json_encode(["status" => "fail", "message" => "No valid media binary stream detected."]));
}
$tmpFilePath = $_FILES[$fileKey]['tmp_name'];
// Handshake with Cloudinary Engine
$cloudinaryUrl = "https://api.cloudinary.com/v1_1/" . CLOUDINARY_CLOUD_NAME . "/image/upload";
$payload = [
'file' => new CURLFile($tmpFilePath),
'upload_preset' => CLOUDINARY_UPLOAD_PRESET
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $cloudinaryUrl);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode !== 200 || !$response) {
http_response_code(502);
die(json_encode(["status" => "fail", "message" => "CDN ingestion processing failure."]));
}
$responseData = json_decode($response, true);
$secureCdnUrl = $responseData['secure_url'] ?? '';
if (empty($secureCdnUrl)) {
http_response_code(502);
die(json_encode(["status" => "fail", "message" => "Asset resolution parsing failed."]));
}
// Since Instagram splits uploading and text configuring into two completely separate actions,
// we provision a quick temporary cache cookie to hold the URL string until the configure script fires next.
setcookie("pending_media_" . $uploadId, $secureCdnUrl, time() + 300, "/");
http_response_code(200);
echo json_encode([
"upload_id" => $uploadId,
"status" => "ok"
]);
exit;