[mod_python] Form upload

Graham Dumpleton grahamd at dscpl.com.au
Thu May 18 19:14:42 EDT 2006


Please keep followups on the mailing list. Response at end of message.

jaba at findyourcore.com wrote ..
> > jaba at findyourcore.com wrote ..
> >> heres my code:
> >>
> >> #########upload.py#########
> >>
> >> from mod_python import util
> >> import sys
> >> def handler(req):
> >>     sys.stdout=sys.stderr=req
> >>     form=util.FieldStorage(req)
> >>     if form.has_key("file"):print form.list[0].file.getvalue()
> >>     print "<form method=post><input type=file name=file></form>"
> >>
> >> ###########################
> >>
> >> the problem is, it only returns the filename, not the file contents.
> >> Whats wrong?
> >
> > Am sure someone else will answer your real question, I can't remember
> > off the top of my head how to handle files as not something I do.
> > Anyway, would like to point out some other things you are doing wrong.
> >
> > The main issue is that you MUST not set sys.stdout/sys.stderr to the
> > req object and then use "print". This will blow up in bad ways if you
> > are using a multithreaded MPM such as used on Win32 or "worker"
> > on UNIX. If you really want to use "print", leave sys.std??? alone and
> > use:
> >
> >   if form.has_key("file"):
> >     print >> req, form.list[0].file.getvalue()
> >   print >> req, "<form method=post><input type=file name=file></form>"
> >
> > Ie., use ">>" redirection to make it print to the req object.
> >
> > Since you are returning HTML, also make sure you set content type.
> >
> >   req.content_type = 'text/html'
> >
> > before first content written. Don't assume browsers will always guess
> > correctly.
> >
> > Also, I assume that not returning apache.OK is purely because you
> > didn't need it necessary to supply all the code????
> >
> > Graham
> 
> How would it blow up? (its a little annoying doing the "print >> req,"
> all
> the time.
> And yes, your assumption is correct.

In a multithreaded MPM, multiple requests can be executing in the same
Apache child process at the same time. Further, they could be executing
in the same handler at the same time. If a handler modifies sys.std???
and sets it to the req object for a particular request, it may get replaced
by that for a different request before it even got to use it. Thus you will
get responses going back to the wrong clients. Further, after a handler
returns, the req object internals have been deleted, although the Python
wrapper will not. Any write to the req object at that point will cause
Apache to crash usually.

Graham


More information about the Mod_python mailing list