Recipe14.3.Uploading Files with CGI


Recipe 14.3. Uploading Files with CGI

Credit: Noah Spurrier, Georgy Pruss

Problem

You need to enable the visitors to your web site to upload files by means of a CGI script.

Solution

Net of any security checks, safeguards against denial of service (DOS) attacks, and the like, the task boils down to what's exemplified in the following CGI script:

#!/usr/local/bin/python import cgi import cgitb; cgitb.enable( ) import os, sys try: import msvcrt             # are we on Windows? except ImportError: pass       # nope, no problem else:                          # yep, need to set I/O to binary mode     for fd in (0, 1): msvcrt.setmode(fd, os.O_BINARY) UPLOAD_DIR = "/tmp" HTML_TEMPLATE = \ """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html><head><title>Upload Files</title> </head><body><h1>Upload Files</h1> <form action="%(SCRIPT_NAME)s" method="POST" enctype="multipart/form-data"> File name: <input name="file_1" type="file"><br> File name: <input name="file_2" type="file"><br> File name: <input name="file_3" type="file"><br> <input name="submit" type="submit"> </form> </body> </html>""" def print_html_form( ):     """ print the form to stdout, with action set to this very script (a        'self-posting form': script both displays AND processes the form)."""     print "content-type: text/html; charset=iso-8859-1\n"     print HTML_TEMPLATE % {'SCRIPT_NAME': os.environ['SCRIPT_NAME']} def save_uploaded_file(form_field, upload_dir):     """ Save to disk a file just uploaded, form_field being the name of the         file input field on the form.  No-op if field or file is missing."""     form = cgi.FieldStorage( )     if not form.has_key(form_field): return     fileitem = form[form_field]     if not fileitem.file: return     fout = open(os.path.join(upload_dir, fileitem.filename), 'wb')     while True:         chunk = fileitem.file.read(100000)         if not chunk: break         fout.write(chunk)     fout.close( ) save_uploaded_file("file_1", UPLOAD_DIR) save_uploaded_file("file_2", UPLOAD_DIR) save_uploaded_file("file_3", UPLOAD_DIR) print_html_form( )

Discussion

The CGI script shown in this recipe is very bare-bones, but it does get the job done. It's a self-posting script: it displays the upload form, and it processes the form when the user submits it, complete with any uploaded files. The script just saves files to an upload directory, which in the recipe is simply set to /tmp.

The script as presented takes no precaution against DOS attacks, so a user could try to fill up your disk with endless uploads. If you deploy this script on a system that is accessible to the public, do add checks to limit the number and size of files written to disk, perhaps depending, also, on how much disk space is still available. A version that might perhaps be more to your liking can be found at http://zxw.nm.ru/test_w_upload.py.htm.

See Also

Documentation on the cgi, cgitb, and msvcrt standard library modules in the Library Reference and Python in a Nutshell.



Python Cookbook
Python Cookbook
ISBN: 0596007973
EAN: 2147483647
Year: 2004
Pages: 420

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net