[mod_python] req.sendfile() problem

Thomas J. Schirripa tommys at eden.rutgers.edu
Fri Aug 4 13:49:56 EDT 2006

Thanks a lot guys, the problem is fixed. I feel so stupid because it ended up being a naming problem - I thought the path looked okay, and I automatically assumed the name wasn't a problem because I would have thought the IOError message would have said something along the lines of "cannot find file". Anyways, I actually had a question about handling the exception because I did try doing that.

I had req.sendfile() in a try/except block, but in order to to send the error message to the browser....
Here's what I did...

def handler(req):
	fields = util.FieldStorage(req)
	filename = os.path.basename(fields["filename"])
	directory = os.path.dirname(fields["filename"])
	req.headers_out["Content-Disposition"] = "attachment; filename=%s" % filename
	req.content_type = "text/plain"
		req.sendfile("%s/%s" % (directory, filename))
	except IOError, e:
		req.content_type = "text/html"
		req.write("Raised exception reads:\n<br>%s" % str(e))
		return apache.OK
	return apache.OK

Here's what happened:
instead of the IOError displaying in the browser, the file downloaded and had the req.write() message in it:
"Raised exception reads:
<br>Could not stat file for reading"

I thought I read somewhere you can't change the content type after it has been set (a limitation of http -  in fact, this is why I have a seperate sendFile handler... so I can set the content type properly), but I didn't think this would be a problem. Is there a way to get the message to display in the browser instead of sending over an html file with the message?

Thanks again, I don't know what I would do without this mailing list sometimes.

-----Original Message-----

> Date: Fri Aug 04 12:42:37 EDT 2006
> From: "Jim Gallacher" <jpg at jgassociates.ca>
> Subject: Re: [mod_python] req.sendfile() problem
> To: "Thomas J. Schirripa" <tommys at eden.rutgers.edu>
> Thomas J. Schirripa wrote:
> > Before stating my problem, let me say that I am running apache version 2.0.52, mod_python 3.2.8, python 2.3, all on Redhat Enterprise Linux WS release 4.
> > 
> > Basically I have a webpage where the client uploads a file and some scripts/programs run on the server and produce output files. Some of this output is spit out onto another webpage, but I want to give the client the option to download the output files. Since I am using multiple webpages, I had to figure out a way to transfer data from one page to another. The only sensible solution that I could figure out was to use psp to feed variables from my handlers into hidden form inputs in my template. From the output html page, the client can click a submit button next to the output filename that says "download". The hidden form inputs have the information as to where the file is located on the server, and the action on the form refers to my sendFile handler. That handler looks like this:
> > 
> > def handler(req):
> > 	fields = util.FieldStorage(req)
> >         #Note: the filename is an absolute path, so I am going to split that up into directory and filename for clarity
> > 	filename = os.path.basename(fields["filename"])
> > 	path = os.path.dirname(fields["filename"])
> > 	req.headers_out["Content-Disposition"] = "attachment; filename=%s" % filename
> > 	req.content_type = "text/plain"
> > 	req.sendfile("%s/%s" % (directory, filename))
> > 	return apache.OK
> > 
> > I am not sure if I am using req.header_out or req.content-type correctly or how critical those lines are (I found it in another post), but my problem is that I am getting a file to download with the proper filename, BUT the file has a mod_python error message in it that reads:
> > 
> > IOError: Could not stat file for reading
> > 
> > and the error points to the line with req.sendfile(). Can anyone tell me what's going on and how to correct this?
> An exception is being raised and mod_python is dumping the traceback in
> the response. You should wrap req.sendfile() in a try/except block, and
> if and exception is raised send a proper error message to the browser.
> sendfile() needs to stat the file so it can set the content length
> header. You are getting the IOError because the file does not exist or
> there is a permission problem. Make sure you are using absolute paths
> for sendfile(). Also, it goes without saying that the filename provided
> by in the request should not be trusted. Do some checking to ensure it
> is valid value.
> Jim

More information about the Mod_python mailing list