[mod_python] requests are blocking when using req.sendfile

Matt Barnicle mattb at wageslavery.org
Tue Sep 23 22:07:04 EDT 2008

> 2008/9/23 Matt Barnicle <mattb at wageslavery.org>:
>> i'm having an issue with our site, which seems to be directly
>> related to using req.sendfile.  on our site, we have secure music
>> downloads.  the user has to go through a series of steps in order
>> to
>> gain access to the music (fyi, we run a legitimate service, not a
>> pirate or warez site).  just some background info..  basically we
>> can't offer a direct download link or the security can be
>> bypassed.
>> so downloading is done through the handler, which runs the checks,
>> and if everything looks good, the file is sent to the browser
>> using
>> req.sendfile with the local path to the file on disk.
>> it works..  but the problem is, requests start backing up whenever
>> a
>> download is being sent.  it looks like new requests are being sent
>> to the apache process that is tied up sending the download file.
>> i
>> don't understand why this is happening though.  i would think that
>> while it's sending the file, no new requests would be queued in
>> that
>> process.  i can verify this easily by downloading a file, and
>> while
>> it's downloading, clicking on a link on the site from the same
>> window in which i downloaded in.  the request will stay in the
>> state (according to mod_status) until the download is finished,
>> then
>> the page will load and the queue will clear up.  now if i change
>> the
>> download link to a static file, served directly by apache, this
>> problem disappears.
>> what can i do to fix this?  it's a major issue right now.  many
>> times a day you can go to the site and it will hang for perhaps 1
>> to
>> 3 minutes, then it will load, due to the above described
>> situation.
>> version notes:
>> CentOS release 5 (Final)
>> apache 2.2.3
>> mod_python 3.2
>> using prefork compiled into apache.  misc apache configuration:
>> KeepAlive Off
>> <IfModule prefork.c>
>>  StartServers       8
>>  MinSpareServers    5
>>  MaxSpareServers   20
>>  ServerLimit      256
>>  MaxClients       256
>>  MaxRequestsPerChild  4000
>> </IfModule>
>> thank you for your time and consideration..
> 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)

- m@

More information about the Mod_python mailing list