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
|