On Windows, paths like "//foo/bar" are allowed and
sometimes necessary. AOLserver's Ns_NormalizePath() C
function incorrectly changes that path to "/foo/bar".
Tcl, on the other hand, does the right thing.
In AOLserver 4.0.10, the following test script gives
the following results on Windows and Linux:
ns_return 200 text/plain "
[ns_normalizepath
{//unixbox/vmhome/log/mysite-win-error.log}]
[file normalize
{//unixbox/vmhome/log/mysite-win-error.log}]
"
Run on Windows XP (bad):
/unixbox/vmhome/log/mysite-win-error.log
//unixbox/vmhome/log/mysite-win-error.log
Run on Linux (ok):
/unixbox/vmhome/log/mysite-win-error.log
/unixbox/vmhome/log/mysite-win-error.log
Logged In: YES
user_id=43168
I noticed this because I'm running AOLserver on Windows, but
having AOLserver write its server log to a Linux box over
Samba. Thus, the full path to my server log is:
"//pinky/vmhome/log/mysite-error.log"
When I roll the server log every night, the log roll works
(after fixing bug #994224), but that also calls
Ns_PurgeFiles() to delete excess old logs, which fails with
this error:
[14/Mar/2005:00:00:02][3996.2912][-sched-] Error: rollfile:
failed to purge files:opendir(/pinky/vmhome/log) failed: 'No
such file or directory'
Of course, the problem is that from Windows there is no such
directory as "/pinky" (1 slash), but "//pinky" (2 slashes)
definitely does exist.
Ns_NormalizePath() is fairly short so the simplest solution
is probably just to fix it. But at the moment I'm not
seeing what part eats the slash.
Tcl already does this (and probably other stuff as well)
correctly. However, the functionality is all in
TclpObjNormalizePath(), which insists on having a Tcl
interp, using Tcl_Objs, etc., no C API that could be made
easily compatible with Ns_NormalizePath().
TclpObjNormalizePath() is also MUCH more complicated.
Logged In: YES
user_id=43168
Ok, I figured out a way to fix this; it's very simple. I
created the patch like this:
cvs diff -u -r aolserver_v40_r10 nsd/pathname.c >
patch-bug-1162890-v40r10.txt
Logged In: YES
user_id=661593
On linux // is interpreted the same as /, so there is no need to remove
the extra /, how about other Unix OS? Another thing to check is if the
HTTP URI allows empty path segments. It probably does. AOLserver
currently ignores the extra / in the url. Is there a problem with your
patch if there are differences in URI/OS paths?
I'll check the URI spec to to see what I find, AOLserver already has one
problem with URI interpretation. I believe that each path segment is
now allowed to have a parameter section.
Logged In: YES
user_id=43168
TclpObjNormalizePath() is documented to modify the existing
path in place, but Ns_NormalizePath() however does not work
that way.
Ns_NormalizePath() reads the path and constructs and
entirley new one in the Ns_DString *dsPtr provided by the
caller. Thus, my tiny little patch simply writes out one
additional slash in the case where that makes sense - when
the two slashes are the very beginning of the path.
Ns_NormalizePath()'s handling of all other slashes in the
path is unchanged by my patch.
In the long run I think it would be much better to just use
Tcl's implementation of many things like this. However, in
this particular case Ns_NormalizePath() is a published
public function so if we do decide to simply deprecate it
entirely, it needs to be marked as such for a long time
before actually removing it. Also, I suspect that
Ns_NormalizePath() is used on EVERY SINGLE hit to the server
as part of decoding URLs to file paths to be served, so it's
speed and bug-freeness might be very important.
There is also the broader question, of why is stuff like log
rolling being done in C code AT ALL? Rolling the log once a
night is obviously of no performance significance, so why
isn't it written entirely in Tcl rather than C?
Logged In: YES
user_id=43168
I've committed the fix in the small patch below, on the
4.0.x branch.