[mod_python] finding length of user file before uploading

Graham Dumpleton grahamd at dscpl.com.au
Fri Apr 14 22:54:50 EDT 2006


On 15/04/2006, at 12:36 PM, greg wrote:

> I want a script (PSP preferred, custom handler if need be) that can
> cancel an upload if the file is too large, or is taking too long.
> The list archives have a few hacks for custom uploads using:
>
> 	util.FieldStorage(req, file_callback=FileFactory)
>
> However, this parameter is not in the official docs, and several
> previous posters noticed the behaviour breaking between versions.
> My system is Debian, Apache2, mod_python 3.1.3-3.
> When I try the file_callback trick, I get:
>
>   File "/var/www/upload.psp", line 40, in ?
>     frm = util.FieldStorage(req, file_callback=make_file)
>
> TypeError: __init__() got an unexpected keyword argument  
> 'file_callback'
>
>
> I presume that undocumented feature has become extinct in recent  
> versions.
>
> And, even if it had worked, it still doesn't relay the size of the
> file until the transfer is eating time and memory.
> I would like to avoid making a custom handler that gets the data  
> directly from the client--it seems like I would re-invent the  
> wheel. A slower wheel.
>
> What is the best way to aquire the filesize before the upload starts?

The file_callback and field_callback parameters are new features in
unreleased 3.2.9 and 3.3.X. That is why you can find them. See
documentation at:

   http://svn.apache.org/viewcvs.cgi/httpd/mod_python/branches/3.2.x/ 
Doc/modpython4.tex?rev=393781&view=markup

The simplest way to avoid uploading something that is too big is to
check the content length of the incoming request. You would need
to use a custom handler for that though.

Because some handlers such as mod_python.publisher have already
consumed request content by the time your code has been called,
the simplest thing to do is to do the check in a fixup handler which is
run in addition too, but before the normal content handler.

For example:

   PythonFixupHandler check_for_large_uploads

   # check_for_large_uploads.py

   from mod_python import apache

   UPLOAD_LIMIT = 1000000

   def fixuphandler(req):
     length = int(req.headers_in.get("Content-Length", "0"))
     if length >= UPLOAD_LIMIT:
       req.content_type = 'text/plain'
       req.status = apache.HTTP_BAD_REQUEST
       req.write('upload too big\n')
       return apache.DONE

     return apache.OK

The important bit is that the fixup handler must cause call to following
content handler to be aborted. This is why it explicitly sets req.status
and then returns apache.DONE instead of apache.OK. The handler
needs to also construct any custom response.

Not sure there is a simple way of handling an upload that takes too
long. I haven't looked at the file_callback feature to see whether that
might make it easier.

Graham



More information about the Mod_python mailing list