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! !