[mod_python] requests are blocking when using req.sendfile

Matt Barnicle mattb at wageslavery.org
Thu Sep 25 01:12:11 EDT 2008


> 2008/9/24 Matt Barnicle <mattb at wageslavery.org>:
>>> Are you setting a content length on the response before calling
>>> req.sendfile()?
>>>
>>> How many concurrent requests for these files are you receiving and
>>> how long does it take to download a file?
>>>
>>> Graham
>>
>> yes, i believe so..  now that you mention it, i haven't verified the
>> file size from the code below, i will do that to be sure.  here is
>> the code:
>>
>> file_path = self.conf.run.app_folder + 'public' + download.path
>> file_stat = os.stat(file_path)
>> file_size = str(file_stat.st_size)
>>
>> self.req.headers_out['Content-Length'] = file_size
>> self.req.headers_out['Content-Disposition'] = 'attachment;
>> filename=%s' % os.path.basename(file_path)
>>
>> bytes_sent = self.req.sendfile(file_path)
>
> BTW, now that you are using mod_python 3.3.1, instead of using
> req.sendfile(), you could possibly delegate serving of the static
file
> back to Apache. From memory this can be done using:
>
>   req.filename = self.conf.run.app_folder + 'public' + download.path
>   req.finfo = apache.stat(req.filename, apache.APR_FINFO_MIN)
>   return apache.DECLINED
>
> By returning apache.DECLINED you say mod_python handler will not
> actually handle it, and by having updated req.filename and
> req.fileinfo updated to new file, when it falls through to
> default-handler it should serve it as static file.
>
> Doing it this way should bypass prior Apache access control checks.
> Thus file doesn't need to be in Apache document tree or anywhere else
> that is accessible.
>
> I believe doing it this way also has benefit that Apache will
> automatically set various headers that you probably wouldn't be.
>
> Please let us know if this alternate method works.
>
> Graham

i'm trying to get this working, but running into a snag..  i'm
actually running a custom written MVC framework to serve the site
pages.  the way it was written was to have mod_python be the handler
for all requests, and a rewrite rule is written to route all
requests through index.psp which sits in the document root.  i tried
adding this code to the index.psp but found quickly that it wouldn't
work.  so it seemed to me that the correct way to do it was to
change the way pages are served, and run everything through a proper
request handler, which could return the apache status as described
above.  had to restructure some of the code, but i did eventually
*sort of* get it working.

first, i can't seem to figure out how to get all requests, no matter
what the URI, to be processed through the handler (which for all
intents and purposes let's call the base controller).  i tried the
following but it doesn't seem to do what i want:

DocumentRoot /var/www/my/application/public
<Directory /var/www/my/application/public>
 AddHandler python-program .py
 PythonHandler myhandler
</Directory>

with the above configuration, when i go to the home page, i see a
directory listing instead of the handler being executed..

the previous way this was working was to put a rewrite rule in
.htaccess that routes all requests through index.psp.  so i tried
changing that to route everything through myhandler.py, and that
does sort of work, but then i can't seem to read the uri that's in
the location bar.  when i read req.uri, it's just /myhandler.py. 
the way we were doing that before was with the following code, which
no longer works now that i'm serving out of a custom handler, it
throws an error:

req.add_common_vars()
env_vars = req.subprocess_env
uri = env_vars['REDIRECT_URL'].strip('/')

i'm so close to getting this working!

thanks for your help,

- m@



More information about the Mod_python mailing list