Big File Upload

This script is a more complete version of the last one. It buffers file IO avoiding to memory starve the server if the file is a bit bigger. There is no drawback in buffering file IO, so always do it.

<html><body>
<%
# Generator to buffer file chunks
def fbuffer(f, chunk_size=10000):
   while True:
      chunk = f.read(chunk_size)
      if not chunk: break
      yield chunk
      
if form.has_key('file') and form['file'].filename:
   # A nested Field object holds the file
   fileitem = form['file']

   try: # Windows needs stdio set for binary mode.
      import msvcrt
      msvcrt.setmode (0, os.O_BINARY) # stdin  = 0
      msvcrt.setmode (1, os.O_BINARY) # stdout = 1
   except ImportError:
      pass

   # strip leading path from file name to avoid directory traversal attacks
   fname = os.path.basename(fileitem.filename)

   # build absolute path to files directory
   dir_path = os.path.join(os.path.dirname(req.filename), 'files')

   f = open(os.path.join(dir_path, fname), 'wb', 10000)

   # Read the file in chunks
   for chunk in fbuffer(fileitem.file):
      f.write(chunk)
   f.close()
   
   message = 'The file "%s" was uploaded successfully' % fname
%>
<p><%= message %></p>
<p><a href="">Upload another file</a></p>
<%
else:
   #
%>
<form enctype="multipart/form-data" action="" method="post">
<p>File: <input type="file" name="file"></p>
<p><input type="submit" value="Upload"></p>
</form>
<%
#
%>
</body></html>