I looked at the code a bit closer. The ns_returnfile and ns_respond
commands both call Ns_ConnReturnFile, the public API to the underlying
FastPath. It does more than just blast the content -- it handles:
-- respond "not found" if file doesn't exist
-- sets "last modified header" based on mtime
-- returns "not modified" if client sent "if-modified-since"
-- returns headers only if a HEAD request
-- sets mimetype and contentlength
-- caches, mmap's, or simply opens the fd and sends, chunk by chunk
The code is a bit nested, with a few layers of code which handle
similar cases (send file, FILE *, fd, etc.). It's not 100% perfect
because the file could change between the stat to check existence and
get size/mtime for header construction and the actual send. There's
even a note that say something like "silently ignore truncated
file..." deeper down so that if fastpath stats a file of size x but
opens and starts sending a smaller file, it'll just silently quit
after sending what it found. By comparison, the ADP template read/
parse/cache code attempts to catch that case -- it tries up to 10
times in ParseFile to get a consistent fstat/read on the open file
(you can see that in adpeval.c).
Overall, this means ns_returnfile is designed to mimic the core file-
send/fastpath stuff as if there was no Tcl code involved at all --
performance, pitfalls and all. Whether fastpath is significantly
smarter or dumber sending static content than, say, Apache, I can't
say. This also means that a new "-cache 1/0" option to
ns_returnfile (default 0 or 1, subject to debate) could be useful but
not quite the same as "just send this file..." One would still get
the result AOLserver would have generated (not found, not modified,
etc.) unless all that was disabled as well.
By comparison, ns_returnfp is more basic -- it assumes it's sending
stuff from an open channel, just sets basic headers, and has none of
the "not found", "not modified", etc. type logic. Because the docs
don't mention this, I think some folks expect ns_returnfile to be just
this:
set fp [open file]
ns_returnfp $fp
close $fp
BTW: I mentioned that I thought it worked that way in the past but I
think I was wrong. Checking the CVS logs and diff'ing the files with
rev 1.1 way back in 2000 ns_returnfile was calling the fastpath and
fastpath was using the dev/inode pair for the cache key on Unix.
Overall, it seems one thing to do would be to switch to filename-based
cache keys by default, leaving the dev/inode pair as an option for
folks who run sites with large symlinks and want to benefit from
caching objects just once. I think that should avoid the data
corruption cases John pointed out with minimal downside. We could
also modify ns_returnfile to behave as above, calling ns_returnfp, but
I'm thinking that may break more than it fixes if folks are assuming
the behavior it has now (e.g, an ns_returnfile of an image where they
expect the not-modified responses).
-Jim
On Aug 20, 2008, at 9:23 AM, Titi Alailima wrote:
-----Original Message-----
From: AOLserver Discussion [mailto:[EMAIL PROTECTED] On
Behalf Of Jim Davidson
Sent: Tuesday, August 19, 2008 8:39 PM
To: AOLSERVER@LISTSERV.AOL.COM
Subject: Re: [AOLSERVER] Data "corruption" with fastpath caching
Your right, the code snippet below could trip over a race condition
as
you've described. But, that's not reason enough to change the
fastpath, it's reason to better document the behavior so folks don't
write code that uses ns_returnfile for temporary, dynamic content.
Although fastpath takes care to be correct in most cases (e.g.,
stat'ing the file on each request and serializing read on cache
miss),
the "fast" in fastpath is because it's primarily designed to return
simple static content with minimal overhead.
BTW: I believe the ns_returnfile command didn't use the fastpath
originally -- I think it just opened and sent the content. It was
changed because folks asked for it to go faster I think -- can't
recall.
This sounds like the problem. Not a bug with fastpath, but a
questionable decision to take an apparently generic command and
apply a situation-specific optimizer to it that returns bad results
when applied outside of its design parameters. It seemed like a
valid assumption at the time, just as John's code seemed to be
making valid assumptions, but it just seems to have led to asses
being made left and right.
Is there any way to make ns_returnfile's use of fastpath
configurable, and turn _that_ off by default? Or would that be
essentially the same as just turning fastpath off entirely? I must
confess my ignorance of where fastpath gets used.
Titi Ala'ilima
Lead Architect
MedTouch LLC
1100 Massachusetts Avenue
Cambridge, MA 02138
617.621.8670 x309
--
AOLserver - http://www.aolserver.com/
To Remove yourself from this list, simply send an email to <[EMAIL PROTECTED]
> with the
body of "SIGNOFF AOLSERVER" in the email message. You can leave the
Subject: field of your email blank.
--
AOLserver - http://www.aolserver.com/
To Remove yourself from this list, simply send an email to <[EMAIL PROTECTED]>
with the
body of "SIGNOFF AOLSERVER" in the email message. You can leave the Subject:
field of your email blank.