Bolot Kerimbaev wrote:

> Okay, I'm officially announcing that people are welcome to contribute to the
> Comanche project. [...]
> 
> Most notably, I'd like to point you to page #15, 'Comanche Development
> Trail', where I'd like to list all known bugs and solicit ToDos/wishes.

Hi!

I fixed a few of the problems mentioned on the wiki page.  Here's the
change set comment:

- Make ''self halt'' uncatchable by ''[...] on: Error do: [...]''.  This
enables breakpoints in #process: and other methods.

- Fix a bug in #parseHttpHeader: if the header is empty.  The methods
was returning self instead of the empty header dictionary.

- answer the cookie in addCookie: which conforms to other Smalltalk add
methods.

- Correct an 'off-by-one' error in pvtReadRequestFrom: which caused the
first letter in the first header to be missing.

- add an accessor for the url without the GET request parameters. 
Actually, I think you always want to access either the simple url or the
parameter string but never both.  I created a new accessor to stay
compatible.

- add support for multiple parameters (which is needed for check boxes
and multiple selection list boxes) as a hack.  For every parameter X
which has more than one value, the second, third etc values are stored
in an OrderedCollection with a key 'X continued'.  Actually every
formField should be an OrderedCollection instead of a single value but I
didn't change it to stay compatible. So it's a great hack for now.


bye
-- 
Stefan Matthias Aust             Projektleiter/Softwareentwicklung
Baltic Online Computer GmbH,    Alter Markt 1-2,        24103 Kiel
Fon: +49 (0) 431-54003-0 Fax: -99      http://www.baltic-online.de
'From Squeak2.8alpha of 18 January 2000 [latest update: #1819] on 9 February 2000 at 
6:00:29 pm'!
"Change Set:            ComPatches
Date:                   9 February 2000
Author:                 Stefan Matthias Aust

- Make ''self halt'' uncatchable by ''[...] on: Error do: [...]''.  This enables 
breakpoints in #process: and other methods.

- Fix a bug in #parseHttpHeader: if the header is empty.  The methods was returning 
self instead of the empty header dictionary.

- answer the cookie in addCookie: which conforms to other Smalltalk add methods.

- Correct an 'off-by-one' error in pvtReadRequestFrom: which caused the first letter 
in the first header to be missing.

- add an accessor for the url without the GET request parameters.  Actually, I think 
you always want to access either the simple url or the parameter string but never 
both.  I created a new accessor to stay compatible.

- add support for multiple parameters (which is needed for check boxes and multiple 
selection list boxes) as a hack.  For every parameter X which has more than one value, 
the second, third etc values are stored in an OrderedCollection with a key 'X 
continued'.  Actually every formField should be an OrderedCollection instead of a 
single value but I didn't change it to stay compatible. So it's a great hack for now."!


!Exception class methodsFor: 'exceptionSelector' stamp: 'sma 2/9/2000 11:48'!
handles: exception
        "Determine whether an exception handler will accept a signaled exception."

        (exception isKindOf: Halt) ifTrue: [^ false].
        ^ exception isKindOf: self! !


!ExceptionSet methodsFor: 'exceptionSelector' stamp: 'sma 2/9/2000 11:43'!
handles: anException
        "Determine whether an exception handler will accept a signaled exception."

        ^ exceptions anySatisfy: [:each | each handles: anException]! !


!HttpAdaptor class methodsFor: 'utilities' stamp: 'sma 2/9/2000 17:40'!
parseHttpHeader: string
        | header key value start end more colonPos fieldDelims lastKey keyValueDelim |
        "TODO: support multi-line headers (if line starts with a separator, append to 
last"
        header _ Dictionary new.
        string isEmptyOrNil ifTrue: [^ header].
        fieldDelims _ String crlf asCharacterSet.
        keyValueDelim _ $:.
        more _ true.
        start _ 1.
        lastKey _ ''.
        [end _ string indexOfAnyOf: fieldDelims startingAt: start.
        end == 0
                ifTrue: [end _ string size. more _ false]
                ifFalse: [end _ end - 1].
        (end >= start and: [start < string size])
                ifTrue: [
                        (string at: start) isSeparator
                                ifTrue: [header at: lastKey put: ((header at: 
lastKey), (string copyFrom: start to: end))]
                                ifFalse: [colonPos _ string indexOf: keyValueDelim 
startingAt: start.
                                        (colonPos > end or: [colonPos == 0])
                                                ifTrue: [key _ (key _ string copyFrom: 
start to: end) asLowercase.
                                                        value _ '']
                                                ifFalse: [key _ (key _ string 
copyFrom: start to: colonPos-1) asLowercase.
                                                        value _ (value _ string 
copyFrom: colonPos+1 to: end) withBlanksTrimmed]].
                        key isEmpty
                                ifFalse: [header at: key put: value.
                                        lastKey _ key.
                                        key _ ''].
                        start _ string skipDelimiters: String crlf startingAt: end+1].
        more] whileTrue.

        ^header! !


!HttpRequest methodsFor: 'accessing' stamp: 'sma 2/8/2000 17:19'!
addCookie: aCookie

        ^ self newCookies add: aCookie! !

!HttpRequest methodsFor: 'accessing' stamp: 'sma 2/8/2000 18:20'!
simpleUrl
        ^ self url copyUpTo: $?! !

!HttpRequest methodsFor: 'private' stamp: 'sma 2/9/2000 11:56'!
pvtReadRequestFrom: aStream
        | headerString statusString statusLine i |

        headerString _ aStream upToAll: self endOfRequestMarker.
        i _ headerString findString: String crlf.
        i = 0
                ifFalse:
                        [statusString _ headerString copyFrom: 1 to: i-1.
                        headerString _ headerString copyFrom: i+2 to: headerString 
size]
                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"! !


!HttpRequest class methodsFor: 'http stuff' stamp: 'sma 2/9/2000 14:52'!
decodeUrlEncodedForm: string
        | dict key value start end eqSignPos more |
        dict _ Dictionary new.
        string isEmptyOrNil ifTrue: [^dict].
        more _ true.
        start _ 1.
        [end _ string indexOf: $& startingAt: start.
        end == 0
                ifTrue: [end _ string size. more _ false]
                ifFalse: [end _ end - 1].
        eqSignPos _ string indexOf: $= startingAt: start.
        (eqSignPos > end or: [eqSignPos == 0])
                ifTrue: [key _ (key _ string copyFrom: start to: end) unescapePercents 
asLowercase.
                        value _ '']
                ifFalse: [key _ (key _ string copyFrom: start to: eqSignPos-1) 
unescapePercents asLowercase.
                        value _ (value _ string copyFrom: eqSignPos+1 to: end) 
unescapePercents].
        (dict includesKey: key)
                ifTrue: [(dict at: key , ' continued' ifAbsentPut: [OrderedCollection 
new]) add: value]
                ifFalse: [dict at: key put: value].
        start _ end + 2.
        more] whileTrue.

        ^dict! !


Reply via email to