Replies: 3 comments
-
File Upload/Download Issue: Binary File Corruption in Cloud Run + PHPGreat question! The issue you're experiencing is quite common when handling binary files in web applications. Let me help you resolve this step by step. Root Cause AnalysisThe problem occurs because different file types require different handling approaches, particularly for binary files vs. text files. Files like Key Issues and Solutions1. MIME Type ConfigurationFirst, ensure proper MIME type detection and headers: <?php
function getProperMimeType($filename) {
$ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
$mimeTypes = [
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'skp' => 'application/vnd.sketchup.skp', // SketchUp files
'jpg' => 'image/jpeg',
'jpeg' => 'image/jpeg',
'png' => 'image/png',
'pdf' => 'application/pdf',
'webp' => 'image/webp'
];
return $mimeTypes[$ext] ?? 'application/octet-stream';
}
?>2. Proper Upload HandlingEnsure binary-safe file handling during upload: <?php
function uploadFile($uploadedFile, $destination) {
// Validate file
if (!isset($uploadedFile['error']) || $uploadedFile['error'] !== UPLOAD_ERR_OK) {
throw new Exception('Upload failed with error code: ' . $uploadedFile['error']);
}
// Check if file is actually uploaded
if (!is_uploaded_file($uploadedFile['tmp_name'])) {
throw new Exception('Security error: File not uploaded via HTTP POST');
}
// Get file info
$originalName = basename($uploadedFile['name']);
$mimeType = getProperMimeType($originalName);
// Create destination directory if it doesn't exist
$destDir = dirname($destination);
if (!is_dir($destDir)) {
mkdir($destDir, 0755, true);
}
// Move file with binary-safe handling
if (!move_uploaded_file($uploadedFile['tmp_name'], $destination)) {
throw new Exception('Failed to move uploaded file to destination');
}
// Verify file integrity
if (!file_exists($destination) || filesize($destination) === 0) {
throw new Exception('File upload verification failed');
}
return [
'filename' => $originalName,
'path' => $destination,
'size' => filesize($destination),
'mime_type' => $mimeType
];
}
?>3. Proper Download HeadersThe most critical part - proper download headers for binary files: <?php
function downloadFile($filePath, $originalName = null) {
if (!file_exists($filePath)) {
http_response_code(404);
die('File not found');
}
$filename = $originalName ?: basename($filePath);
$mimeType = getProperMimeType($filename);
$filesize = filesize($filePath);
// Clear any previous output
if (ob_get_level()) {
ob_end_clean();
}
// Set proper headers for binary files
header('Content-Type: ' . $mimeType);
header('Content-Disposition: attachment; filename="' . addslashes($filename) . '"');
header('Content-Length: ' . $filesize);
header('Content-Transfer-Encoding: binary');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Expires: 0');
// Prevent any additional output
ini_set('output_buffering', 'off');
ini_set('zlib.output_compression', 'off');
// Read and output file in chunks for large files
$handle = fopen($filePath, 'rb');
if ($handle === false) {
http_response_code(500);
die('Cannot read file');
}
while (!feof($handle)) {
$chunk = fread($handle, 8192); // 8KB chunks
echo $chunk;
flush(); // Force output
}
fclose($handle);
exit; // Important: prevent any additional output
}
?>4. Complete Example Implementation<?php
// upload.php
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['file'])) {
try {
$destination = '/path/to/your/cloud/storage/' . uniqid() . '_' . $_FILES['file']['name'];
$result = uploadFile($_FILES['file'], $destination);
echo json_encode([
'success' => true,
'message' => 'File uploaded successfully',
'data' => $result
]);
} catch (Exception $e) {
http_response_code(400);
echo json_encode([
'success' => false,
'message' => $e->getMessage()
]);
}
}
// download.php
if (isset($_GET['file']) && isset($_GET['name'])) {
$filePath = '/path/to/your/cloud/storage/' . basename($_GET['file']);
$originalName = $_GET['name'];
downloadFile($filePath, $originalName);
}
?>5. Cloud Run Specific ConsiderationsFor Google Cloud Run environments, also ensure: <?php
// Add these headers for Cloud Run
header('X-Robots-Tag: noindex');
header('X-Frame-Options: DENY');
// Increase memory and time limits for large files
ini_set('memory_limit', '256M');
ini_set('max_execution_time', 300);
ini_set('max_input_time', 300);
ini_set('post_max_size', '100M');
ini_set('upload_max_filesize', '100M');
?>6. Debugging StepsAdd logging to identify where the corruption occurs: <?php
function debugFileIntegrity($filePath, $stage) {
$hash = hash_file('md5', $filePath);
$size = filesize($filePath);
error_log("[$stage] File: $filePath, Size: $size, MD5: $hash");
return ['hash' => $hash, 'size' => $size];
}
// Use it like this:
$beforeUpload = debugFileIntegrity($_FILES['file']['tmp_name'], 'BEFORE_UPLOAD');
// ... upload process ...
$afterUpload = debugFileIntegrity($destination, 'AFTER_UPLOAD');
// ... download process ...
$beforeDownload = debugFileIntegrity($filePath, 'BEFORE_DOWNLOAD');
?>Common Mistakes to Avoid
Testing Your Fix
Try implementing these changes and let me know if you're still experiencing issues. The key is usually in the download headers and ensuring binary-safe handling throughout the process! Additional Resources |
Beta Was this translation helpful? Give feedback.
-
|
Hey @firloming, It sounds like you're encountering an issue where certain file types, such as Why This HappensWhen a file is downloaded from a server, the browser relies on the Steps to Resolve the Issue
If you've already tried these steps and the issue persists, please provide more details about your implementation, such as the code used for uploading and downloading the files, any relevant server configurations, and the specific behavior observed. This information will help in diagnosing the problem more accurately. Let me know if you need further assistance! |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Why are you starting this discussion?
Question
What GitHub Actions topic or product is this about?
Workflow Deployment
Discussion Details
Hi, I have successfully uploaded .jpg, .png, .pdf, and .rvt files to my volume mount (cloud storage) for my CLOUD RUN app, and I can also download them successfully. However, specific files like .docx, .pptx, and .skp were also uploaded successfully, but when downloaded, the result is a .text file for .skp, and a .zip file for .pptx and .docx. Why?
While certain files are uploading and downloading properly without any error like .webp, .jpg, .png, .pdf, ... So, the method is correct, then what is wrong ?
I use move_uploaded_file() function .
Thank you .
Beta Was this translation helpful? Give feedback.
All reactions