October
27th 2008
A Pythonic Download Controller Script for Pylons

Posted under programming & python

Having a download script can be useful for several reasons, especially when it comes to security. Retrieving a file programmatically instead of through an absolute path would probably have saved my previous employer’s web server the experience of running malicious PHP (and ergo, other malicious system calls) from some script kiddie using a faulty upload script (in my defense my script was under construction).

Recall from PHP’s docs the method to send a direct file stream as a download using the readfile() function:

$file = 'monkey.gif';

if (file_exists($file)) {
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename='.basename($file));
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));
    ob_clean();
    flush();
    readfile($file);
    exit;
}
This allows any links to this script to download the file automagically without having to load a page or separate window. It also gives the programmer the option of supplying a file path to the file being downloaded, whether it be under under the web root or any other file on the filesystem.

Now for the Python script which accomplishes the same thing by streaming the bytes of the file.

import logging
from myproject.lib.base import *

log = logging.getLogger(__name__)

class DownloadController(BaseController):

def index(self):

    file = 'monkey.gif'
    content_type = 'application/x-octet-stream'
    content_disposition = 'attachment; filename='+file

    response.headers['Content-type'] = content_type
    response.headers['Content-disposition'] = content_disposition

    file_bytes = open(file,'r').read()
    file.close()
    return file_bytes

There you have it. With pylons, returning an opened file using read() and changing the response headers allows you to stream the file contents and allows the viewer to open or save the file.

Simple as py.

No Comments »

July
11th 2008
Goodbye LSU, Hello world!

Posted under Uncategorized

I just graduated in CSC from Baton Rouge, LA. Currently, and somewhat frantically, looking for longterm employment. Halp!

Constantly edited resumeĀ here!

… and by constantly, I mean it’s under version control, so as soon as I save and commit, it’s here.

No Comments »