Viewing 19 posts - 1 through 19 (of 19 total)
  • Author
    Posts
  • #6227
    ryushe
    Participant

    Hi there,

    Installed your plugin, which seems really nice.
    However, when attaching a file to a particular page, I’m running into an issue where the file will download only partially. The resulting file cannot be opened. For instance, a 2mb PDF will download as a 1.7mb file.
    Using a direct link to the actual file works just fine.
    I’ve troubleshooted by tailing the Apache log files, but besides showing that a user accessed the link, I’m not getting any further useful info from it. Also looked at the actual file contents with a regular text editor, and the files (at least the headers) seem identical.
    I disabled and enabled the ‘Pretty URLs’ setting as well, in the hopes of that fixing things, but that did nothing.

    I’m using the below shortcode to display the link on the page.

    [download-attachments container="div" title="Related Downloads" display_icon="1" display_user="0"]

    Any ideas on what I should be looking at to fix this?

    Thanks,
    Ryushe

    #6229
    Bartosz
    Keymaster

    Can you post a link to the site, specific page with attachments?

    #6230
    ryushe
    Participant
    This reply has been marked as private.
    #6254
    Bartosz
    Keymaster

    I think this might be a server releated issue, and the way DA serves files might be the case here. We’re planning to extend download methods – this should allow you to find the one suitable to your server.

    Sorry for the inconviniences.

    #6263
    ryushe
    Participant

    No worries, just found it interesting the other plugin does work.
    If it’s a server issue, any idea on where I might look to see if I can fix this?
    As said before, I’d much rather use yours, as the styling options are much better…

    Thanks for your time!

    #6264
    Bartosz
    Keymaster

    @ryushe, I think it’s the plugin issue – the way of serving files, not working properly on your server configuration.

    So it’s not the server itself.

    If you’d like to do some custom development/testing the function responsible for the download is da_download_attachment() located in plugin folder/includes/functions.php
    You may try to modify the headers, possibly comparing what we have in that function to the way the other plugin is handling file download.

    #6266
    ryushe
    Participant

    Alright, I’ll have a play around with it on my dev (identical) server, see if I can get something going. Thanks for pointing me in the right direction!

    #6267
    Bartosz
    Keymaster

    I hope it is the right direction :)

    #6269
    ryushe
    Participant

    Guess we’ll find out, will have a look tomorrow. Thanks!

    #6486
    ryushe
    Participant

    Well, never had as much time as I thought I did, so only got top play around over the weekend.
    I’ve messed with the headers as returned in the da_download_attachment function as you suggested, but for the life of me I can’t get it to work properly.

    Almost completely replaced the contents of the function mentioned with the contents of the other plugin’s download function, but not much difference. I do have somewhat of an idea where the issue lies now though. It’s something to do with the filesize either being incorrectly reported to the browser, or a mismatch between reported filesize and actual filesize. The size of the downloaded file (via the plugin) is smaller than the actual file itself when downloaded either using a direct link, or as listed on the server. Almost seems like it’s getting truncated somehow. I’m at the end of modifying the original download function, so if you have any further ideas, I’m all ears!

    #6487
    ryushe
    Participant

    Fixed it. My own previous reply gave me the idea that it might have something to do with output buffering, and whaddaya know? That’s exactly it.

    Added the following right after the initial header() declarations and before where the buffer gets echo’ed to the user, around line 504 in functions.php :
    ob_clean();
    ob_end_flush();

    Solved all the problems I was having. Files now download exactly as intended. Hope this helps someone else with the same issues.

    #6488
    Bartosz
    Keymaster

    Thx, @ryushe

    So you’re buffering the headers?

    #6490
    ryushe
    Participant

    I suspect there are some other plugins that use buffering and are not closing their buffers correctly. So completely flushing the output buffer before filling it up again with the contents of the attachment seems to have done the trick.

    Below is what the download function in my case looks like right now. It’s a mashup between your original function, the other plugin’s download function, and a few custom things here and there. Probably could be cleaned up quite a bit, but meh. Perhaps it can help someone else…

    /**
     * Process attachment download function
     * 
     * @param 	int $attachment_id
     * @return 	mixed
     */
    function da_download_attachment( $attachment_id = 0) {
    	if ( get_post_type( $attachment_id ) === 'attachment' ) {
    		$uploads = wp_upload_dir();
    		$attachment = get_post_meta( $attachment_id, '_wp_attached_file', true );
    		$filepath = $uploads['basedir'] . '/' . $attachment;
    		$speed = 0;
    
    		$filepath = apply_filters( 'da_download_attachment_filepath', $filepath, $attachment_id );
    
    		if ( ! file_exists( $filepath ) || ! is_readable( $filepath ) )
    			return false;
    
    		// if filename contains folders
    		if ( ( $position = strrpos( $attachment, '/', 0 ) ) !== false ) {
    			$filename = substr( $attachment, $position + 1 );
    		} else {
    			$filename = $attachment;
    		}
    
    	    $mdata = wp_check_filetype($filename);
    	    $content_type = $mdata['type'];
    
    	    $buffer = $speed ? $speed : 1024;
    		$buffer *= 1024; // in bytes
    	    $bandwidth = 0;
    
    	    if (file_exists($filepath))
    	        $fsize = filesize($filepath);
    	    else
    	        $fsize = 0;
    
    		if ( ini_get( 'zlib.output_compression' ) )
    			ini_set( 'zlib.output_compression', 0 );
    
    		nocache_headers();
    		header( "X-Robots-Tag: noindex, nofollow", true );
    		header("Robots: none");
    		header("Content-type: $content_type");
    		header("Content-disposition: attachment;filename=\"{$filename}\"");
    		header("Content-Transfer-Encoding: binary");
    
    		ob_clean();
    		ob_end_flush();
    
    	    if( ( isset($_REQUEST['play']) && strpos($_SERVER['HTTP_USER_AGENT'],"Safari") ) ) {
    	        readfile($filepath);
    	        die();
    	    }
    
    		$file = @fopen($filepath, "rb");
    
    	    //check if http_range is sent by browser (or download manager)
    	    if (isset($_SERVER['HTTP_RANGE']) && $fsize > 0) {
    	        list($bytes, $http_range) = explode("=", $_SERVER['HTTP_RANGE']);
    	        $set_pointer = intval(array_shift($tmp = explode('-', $http_range)));
    	
    	        $new_length = $fsize - $set_pointer;
    	
    	        header("Accept-Ranges: bytes");
    	        header("HTTP/1.1 206 Partial Content");
    	
    	        header("Content-Length: $new_length");
    	        header("Content-Range: bytes $http_range$fsize/$fsize");
    	
    	        fseek($file, $set_pointer);
    	
    	    } else {
    	        header("Content-Length: " . $fsize);
    	    }
    
    	    $packet = 1;
    	
    	    if ($file) {
    			while ( ! feof( $file ) && ( ! connection_aborted()) && $fsize > 0 ) {
    	            if ($fsize > $buffer)
    	                echo fread($file, $buffer);
    	            else
    	                echo fread($file, $fsize);
    	            ob_flush();
    	            flush();
    	            $fsize -= $buffer;
    	            $bandwidth += $buffer;
    	            if ($speed > 0 && ($bandwidth > $speed * $packet * 1024)) {
    	                sleep(1);
    	                $packet++;
    	            }
    	        }
    	        @fclose($file);
    	    }
    
    		update_post_meta( $attachment_id, '_da_downloads', (int) get_post_meta( $attachment_id, '_da_downloads', true ) + 1 );
    
    		die();
    	} else {
    		return false;
    	}
    }
    
    #6491
    Bartosz
    Keymaster

    @ryushe, may I publish it here? (is private now)

    #6492
    ryushe
    Participant
    This reply has been marked as private.
    #6494
    Bartosz
    Keymaster
    This reply has been marked as private.
    #6495
    ryushe
    Participant
    This reply has been marked as private.
    #6527
    ryushe
    Participant

    Right, this needs a lot of further study. I take back when I said I fixed it. Turns out I didn’t.
    When I tested everything, it worked fine, but to be honest I only tested on Chrome on OSX. Everything worked, so I thought it was done, cause why would it be any different in another browser right? Wrong.

    Assume download link is: http://www.domain.com/files/1982/

    Safari on OSX is still having issues right now. Works one time and downloads the whole file, next attempt on same machine or another machine results in just 25kb being downloaded, after which it times out.

    Chrome on Windows simply can’t even reach the file when using pretty URLs. Claims “The webpage at http://www.domain.com/files/1982/ might be temporarily down or it may have moved permanently to a new web address.”. Tried this on Win7 and WinXP with same versions of Chrome, both have the exact same results.

    Internet Explorer is acting similar to Safari, in the sense that it works one time, and not the other. Oddest thing about IE is that the ‘save file’ dialog either shows the actual filename and downloads just fine, or shows ‘1982/’ and can’t do anything with it.

    Haven’t tested with Opera or FireFox yet.

    This is getting bizarre, and I can’t figure out why exactly it’s behaving differently between the same browsers on different OSs. If I do find out more about this, I’ll let you know.

    #6528
    ryushe
    Participant

    Oh, and forgot to mention, Chrome on OSX works just fine…

Viewing 19 posts - 1 through 19 (of 19 total)
  • You must be logged in to reply to this topic.