MyBB Community Forums

Full Version: Adding download resume ability to attachments
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2 3 4
I have actually managed to quickly code this before I leave, I am doing some testing before I post it - just in case.
Excellent !

I am waiting for your replay Heart
You can use this code. It follows the standards and I have tested it both in Chrome and Firefox to make sure that it indeed works, paused a video of 100mb like 20 times and made Media Player play it for me (too lazy to check md5...), it worked.

Let me know if you find any issues.


<?php
/**
 * MyBB 1.6
 * Copyright 2010 MyBB Group, All Rights Reserved
 *
 * Website: http://mybb.com
 * License: http://mybb.com/about/license
 *
 * $Id$
 */

define("IN_MYBB", 1);
define('THIS_SCRIPT', 'attachment.php'); 

ini_set("zlib.output_handler" , "0");

require_once "./global.php";

header('Accept-Ranges: bytes');

// Find the AID we're looking for
if($mybb->input['thumbnail'])
{
	$aid = intval($mybb->input['thumbnail']);
}
else
{
	$aid = intval($mybb->input['aid']);
}

$plugins->run_hooks("attachment_start");

$pid = intval($mybb->input['pid']);

// Select attachment data from database
if($aid)
{
	$query = $db->simple_select("attachments", "*", "aid='{$aid}'");
}
else
{
	$query = $db->simple_select("attachments", "*", "pid='{$pid}'");
}
$attachment = $db->fetch_array($query);

if ($_SERVER['HTTP_RANGE'] && file_exists($mybb->settings['uploadspath']."/".$attachment['attachname'])) {
	$range = explode("=", $_SERVER['HTTP_RANGE']);
	$range = explode("-", $range[1]);
	
	$filesize = $attachment['filesize'];
	
	if ($range[0] === '') {
 		$end = $filesize - 1;
 		$start = $end - intval($range[0]);
 		$partial_download = true;
 	} elseif ($range[1] === '') {
 		$start = intval($range[0]);
 	 	$end = $filesize - 1;
 	 	$partial_download = true;
 	} else {
  	$start = intval($range[0]);
  	$end = intval($range[1]);
  	if ($end > $filesize || (!$start && (!$end || $end == ($filesize - 1)))) {
  		$partial_download = false;
  	} else $partial_download = true;
	}
	
	$partial_download_size = $end - $start + 1; 
}

$pid = $attachment['pid'];

$post = get_post($pid);
$thread = get_thread($post['tid']);

if(!$thread['tid'] && !$mybb->input['thumbnail'])
{
	error($lang->error_invalidthread);
}
$fid = $thread['fid'];

// Get forum info
$forum = get_forum($fid);

// Permissions
$forumpermissions = forum_permissions($fid);

if($forumpermissions['canview'] == 0 || $forumpermissions['canviewthreads'] == 0 || ($forumpermissions['canonlyviewownthreads'] != 0 && $thread['uid'] != $mybb->user['uid']) || ($forumpermissions['candlattachments'] == 0 && !$mybb->input['thumbnail']))
{
	error_no_permission();
}

// Error if attachment is invalid or not visible
if(!$attachment['aid'] || !$attachment['attachname'] || (!is_moderator($fid) && ($attachment['visible'] != 1 || $thread['visible'] != 1 || $post['visible'] != 1)))
{
	error($lang->error_invalidattachment);
}

if(!$mybb->input['thumbnail']) // Only increment the download count if this is not a thumbnail
{
	$attachupdate = array(
		"downloads" => $attachment['downloads']+1,
	);
	$db->update_query("attachments", $attachupdate, "aid='{$attachment['aid']}'");
}

// basename isn't UTF-8 safe. This is a workaround.
$attachment['filename'] = ltrim(basename(' '.$attachment['filename']));

$plugins->run_hooks("attachment_end");

if($mybb->input['thumbnail'])
{
	$ext = get_extension($attachment['thumbnail']);
	switch($ext)
	{
		case "gif":
			$type = "image/gif";
			break;
		case "bmp":
			$type = "image/bmp";
			break;
		case "png":
			$type = "image/png";
			break;
		case "jpg":
		case "jpeg":
		case "jpe":
			$type = "image/jpeg";
			break;
		default:
			$type = "image/unknown";
			break;
	}
	
	header("Content-disposition: filename=\"{$attachment['filename']}\"");
	header("Content-type: ".$type);
	$thumb = $mybb->settings['uploadspath']."/".$attachment['thumbnail'];
	header("Content-length: ".@filesize($thumb));
	$handle = fopen($thumb, 'rb');
	while(!feof($handle))
	{
		echo fread($handle, 8192);
	}
	fclose($handle);
}
else
{
	$ext = get_extension($attachment['filename']);
	
	switch($attachment['filetype'])
	{
		case "application/pdf":
		case "image/bmp":
		case "image/gif":
		case "image/jpeg":
		case "image/pjpeg":
		case "image/png":
		case "text/plain":
			header("Content-type: {$attachment['filetype']}");
			$disposition = "inline";
			break;

		default:
			$filetype = $attachment['filetype'];

			if(!$filetype)
			{
				$filetype = 'application/force-download';
			}

			header("Content-type: {$filetype}");
			$disposition = "attachment";
	}

	if(strpos(strtolower($_SERVER['HTTP_USER_AGENT']), "msie") !== false)
	{
		header("Content-disposition: attachment; filename=\"{$attachment['filename']}\"");
	}
	else
	{
		header("Content-disposition: {$disposition}; filename=\"{$attachment['filename']}\"");
	}
	
	if(strpos(strtolower($_SERVER['HTTP_USER_AGENT']), "msie 6.0") !== false)
	{
		header("Expires: -1");
	}
	
	$handle = fopen($mybb->settings['uploadspath']."/".$attachment['attachname'], 'rb');
	if (!$partial_download) {
		header("Content-length: {$attachment['filesize']}");
		while(!feof($handle))
		{
			echo fread($handle, 8192); 			
		}
	} else {
		header("Content-length: ".($end-$start+1));
		header('HTTP/1.1 206 Partial Content');	
		header('Content-Range: bytes '.$start.'-'.($end+1).'/'.$filesize);
		fseek($handle, $start);
		while($partial_download_size)
		{
			if ($partial_download_size >= 8192) {
				echo fread($handle, 8192);
			} else {
				echo fread($handle, $partial_download_size);
			}
					
			
			$partial_download_size -= 8192;
		}		
	}
	fclose($handle);
}
?>
(Update attachment.php with this code)

Might be a good idea to add this functionality to core MyBB for those with nasty ISPs.

Disclaimer: Do you own testing please to make sure that it works on your forum. I have done limited testing and I can't guarantee that I haven't missed a bug.
SentoWeb , You are very professional

++

Was excellent. And worked very well

Thank you for your help Heart
Please let me know if you find any issues with it as I am planning to use this on an upcoming forum. You're welcome, DJMOKHTAR.
(2014-01-12, 12:11 AM)SentoWeb Wrote: [ -> ]Please let me know if you find any issues with it as I am planning to use this on an upcoming forum. You're welcome, DJMOKHTAR.

All its ok

but When it comes to the end of the download , speed Goes to 0 and could not save the file or very slow saving

see this please :

[attachment=30813]
Your download manager could be saving/moving the file because from what I see it is actually the very last step. Can you try with a regular file and tell me if that is the case or not. Otherwise I will look into this.
hi

I've tested too much

This always happens on the last byte , The last 4 or 5 bytes

I have no problem with other sites Links Such as a vbulletin board
I just realized that I a forgot to account for the byte that I have subtracted when I was calculating the end point.

Line 200 should be updated to this:
header('Content-Range: bytes '.$start.'-'.($end+1).'/'.$filesize);

Would be strange if this was really the issue causing it, let me know how this works out.
Thanks for your replay

I replaced It but still the problem exists
Pages: 1 2 3 4