The story behind the finding of this bug is somewhat amusing. I'm
struggling to make a Swiki suitable for being a staging/editing area for an
online magazine http://monkeyfist.com. When one of the editor's viewed the
swiki on Linux, using Netscape, he didn't get the navigation icons, but, in
the same house :), using Netscape on Win, he did.
Well, step one, we realized that his "anonymity" software didn't send a
user-agent in the http headers. A no-no for us, since the default swiki
actions for the buttons tests for user-agent (to determine whether to use
the gifs or text).
Ok. Fixed that. He added user-agent to his headers. Fine. Bzzt. Still
didn't work. I set up a little "inspector trap" to catch his headers (in
SwikiRequest>>isFramesCapable). Blam. It turned out that we were getting
this weird header 'ser-request'.
Naturally, we assumed that it was a problem with his anonymity software.
After all, all the other browsers worked find.
Next day. He'd updated the anonymity software. No dice. So I decided that
it must be screwing up the headers in a subtle way to must up parsing the
headers. So I "inspector trapped" the headerString before it got parsed.
Blam. It had "User-Agent" in it. Dang. Then I noticed that User-agent was
the *first* header when my friend browsed, but for everything else, it was
last. Aha! A little testing confirmed the the first letter of the first
header was getting chomped, but since the first header is generally
"Host:", it wasn't getting seen.
(Which made me think, oh COOL. One could forward a request to other Squeaks
on the same, or other machines, and do all sorts of need processing based
on what host did the forwarding (e.g., intra- vs. inter-net stuff)...except
for THIS BUG! :))
(But now I know how to do it ;))
Yep, turns out to be a simple little 'off by one' bug. Add 2, rather than 3 :)
This takes me back to the three month debugging PWS marathon Mark and I did
way back when. We did *everything*. We posited all sorts of crazy stuff
about processes and file handles.
Turned out that there was a missing 'file close'. But it felt *gooood* to
find it :)
Enjoy!
Cheers,
Bijan.
-----------
pvtReadRequestFrom: aStream
| headerString statusString statusLine i |
headerString _ aStream upToAll: self endOfRequestMarker.
"headerString inspect." "This is what I mean by 'inspector trap'. It works
like a charm and doesn't screw up your server or client the way a halt
might."
i _ headerString findString: String crlf.
i = 0
ifFalse: [statusString _ headerString copyFrom: 1 to: i-1.
headerString _ headerString copyFrom: i+3 to: headerString
size]
" ^^^^^ Oops! Chops off
the first letter of the first
header. Should be 'i+2'"
ifTrue: [statusString _ headerString.
headerString _ ''].
statusLine _ statusString findTokens: ' '.
"skip CRLFCRLF" aStream next: (self endOfRequestMarker size).
statusLine size = 3
ifTrue: [self pvtMethod: statusLine first.
url _ statusLine second.
self pvtProtocol: statusLine third]
ifFalse: [self error: 'Bad request'].
self pvtHeader: (HttpAdaptor parseHttpHeader: headerString).
self postFields. "force reading/parsing post fields"