Uploading files in chunks using "onflyrange" was working great for large files and resuming uploads. HOWEVER, as the file was being uploaded and the chunks were being added to the file, the file looked complete from the admin end (the file showed no indication that it wasn't fully uploaded).
I've created a solution, by appending ".part" to the end of files being transferred in this way. After the last chunk is added, the file is renamed to take off the ".part". This eliminates confusion and allows admins to easily see if a file is complete without having to download a local copy first.
I've included my code, because I felt like this could be a good addition to a future version of the sample scripts, or to help anyone out that wants this feature. If I were to get a free license from this contribution though, I sure wouldn't mind
First, change the checking for pre-existing files to include the .part
Code: Select all
$fpart = $fhead . ".part";
if (file_exists($fhead) && !(file_exists($fpart)))
{
header("size: ".filesize($fhead));
if ($debug) fwrite($lg," Previously uploaded file found: ".$fhead."\r\n");
}
elseif (file_exists($fpart)){
header("size: ".filesize($fpart));
if ($debug) fwrite($lg," .part file found: ".$fpart."\r\n");
}
else{
if ($debug) fwrite($lg," No file found"."\r\n");
header("HTTP/1.1 404");
}
Code: Select all
$file_path_part = $file_path . ".part";
$isPart = (file_exists($file_path_part))?true:false;
$result = FALSE;
if (($resume_enabled == "true") && ($isPart) && (isset($_SERVER['HTTP_CONTENT_RANGE'])))
{
// Resume support.
$range_header = $_SERVER['HTTP_CONTENT_RANGE'];
if (substr($range_header,0,6) == 'bytes ')
{
$minus = strpos($range_header,'-');
$start_offset = substr($range_header,6,$minus-6);
$file_path_tmp = $file_path.".".$start_offset.".".time();
if ($debug) fwrite($lg," move_uploaded_file:".$temp_name." to ".$file_path_tmp."\r\n");
$result = move_uploaded_file($temp_name, $file_path_tmp);
if ($debug) fwrite($lg," move_uploaded_file:".$result."\r\n");
if ($debug) fwrite($lg," Resuming at offset ".$start_offset." with ".$file_path_tmp."\r\n");
$fout = fopen ($file_path_part, "rb+");
if ($debug) fwrite($lg," Writing to: ".$file_path_part."\r\n");
$seekedit = fseek ($fout,$start_offset);
$fin = fopen ($file_path_tmp, "rb");
while (!feof($fin))
{
$read = fread($fin,8192);
fwrite($fout,$read);
}
fclose($fin);
if ($debug) fwrite($lg," Deleting:".$file_path_tmp."\r\n");
unlink($file_path_tmp);
fclose($fout);
if ($debug) fwrite($lg," Resume completed"."\r\n");
if ($_POST["chunkbasesize"] == ($_POST["chunkonflysize"] + $_POST["chunkonflyoffset"])){
//This is the last chunk
if ($debug) fwrite($lg,"Renaming from .part name to complete name: ");
if (file_exists($file_path)) unlink($file_path);
if (rename($file_path_part, $file_path)){
if ($debug) fwrite($lg,"Success"."\r\n");
}else{
if ($debug) fwrite($lg,"Failure"."\r\n");
}
}
}
else
{
if ($debug) fwrite($lg," Cannot resume:".$range_header."\r\n");
}
}
Code: Select all
if (($_POST["chunkbasesize"] > $_POST["chunkonflysize"]) && ($_POST["chunkonflyoffset"] == 0)){
//first chunk, need to upload as .part
if ($debug) fwrite($lg," This is the first chunk of a multipart upload"."\r\n");
if ($debug) fwrite($lg," move_uploaded_file:".$temp_name." to ".$file_path_part."\r\n");
$isPart = true;
$result = move_uploaded_file($temp_name, $file_path_part);
}
else{
//reg upload, only part
if ($debug) fwrite($lg," move_uploaded_file:".$temp_name." to ".$file_path."\r\n");
$result = move_uploaded_file($temp_name, $file_path);
}
if ($debug) fwrite($lg," move_uploaded_file:".$result."\r\n");
}
if ($result)
{
chmod($file_path,0755);
$message = ($isPart)?"$file_name uploaded successfully.":"$file_name.part uploaded successfully.";
return $message;
}
-Jason
jblount (at) ecrsoft (dot) com