"WebServer.st
Early version of my Squeak Web Server. Image roll forward and undo are not yet implemented.
TITLE WebServer.st
AUTHOR Georg Gollmann (gollmann@edvz.tuwien.ac.at)
VERSION 0.1.1
IMAGE VERSION 1.21
PREREQUISITES miscChanges.st
DATE August 19, 1997"!
"Some utility methods for existing classes"!
!Collection methodsFor: 'Web Server' stamp: 'go 8/14/97 13:06'!
asLink
"Return a HTML list of my contents."
| stream |
stream := WriteStream on: ''.
stream nextPutAll: '
'.
self do: [ :item | stream nextPutAll: '- '; nextPutAll: item asLink ].
stream nextPutAll: '
'.
^stream contents! !
!Object class methodsFor: 'HTML Reply' stamp: 'go 8/18/97 15:48'!
asHtml: aRequest
"Return a HTML page for me."
aRequest
title: (self asString);
reply: '- Superclass
- ';
reply: self superclass asLink;
reply: '
- Subclasses
- ';
reply: (self subclasses asSortedCollection: [:a :b | a name < b name ]) asLink;
reply: '
- Comment
- ';
reply: self comment asLink;
reply: '
'
! !
!Object methodsFor: 'Web Server' stamp: 'go 8/14/97 13:00'!
asLink: nameString message: aSelector
"Return HTML code for a link to me using the given name and message selector."
| stream |
stream := WriteStream on: ''.
stream
nextPutAll: '';
nextPutAll: nameString;
nextPutAll: ''.
^stream contents! !
!Object methodsFor: 'Web Server' stamp: 'go 8/14/97 13:14'!
asLink
"Return HTML code for a standard link to me."
^(self respondsTo: #asHtml:)
ifTrue: [ self asLink: self asString message: 'asHtml' ]
ifFalse: [ self asString ]! !
!String methodsFor: 'Web Server' stamp: 'go 8/14/97 13:06'!
asLink
"No fancy link building here."
^self! !
!Socket methodsFor: 'queries' stamp: 'go 8/18/97 11:12'!
peerName
"Return the name of the host I'm connected to."
^NetNameResolver nameForAddress: (self primSocketRemoteAddress: socketHandle) timeout: 60! !
TextConstants at: #CrLfCrLf put: (String with: Character cr with: Character linefeed with: Character cr with: Character linefeed)!
TextConstants at: #HttpHeader put: 'HTTP/1.0 200 OK', (String with: Character cr with: Character linefeed), 'Content-Type: text/html', (TextConstants at: #CrLfCrLf)!
TextConstants at: #HttpAuthorize put: ('HTTP/1.0 401 Unauthorized', (String with: Character cr with: Character linefeed), 'WWW-Authenticate: Basic realm="Squeak"', (TextConstants at: #CrLfCrLf), 'Unauthorized
').!
"The web server proper."!
Object subclass: #WebRequest
instanceVariableNames: 'peerName userId message fields connection log '
classVariableNames: 'LinkResolver ObjectNames ServerActive UserMap '
poolDictionaries: 'TextConstants '
category: 'Web Server'!
!WebRequest methodsFor: 'Processing' stamp: 'go 8/13/97 14:56'!
decodeFields: aString
"Convert the form fields in aString to a query dictionary."
| query dict i key value |
query := aString findTokens: '&'.
dict := Dictionary new.
query do: [ :tag |
i := tag indexOf: $=.
key := tag copyFrom: 1 to: i - 1.
value := i < tag size ifTrue: [ self unEscape: (tag copyFrom: i + 1 to: tag size) ] ifFalse: [ nil ].
(dict includesKey: key)
ifFalse: [ dict at: key put: value ]
ifTrue: [
((dict at: key) isKindOf: String)
ifTrue: [ dict at: key put: (OrderedCollection with: (dict at: key)) ].
(dict at: key) add: value
]
].
^dict! !
!WebRequest methodsFor: 'Processing' stamp: 'go 8/18/97 13:42'!
getReply
"Generate the reply."
| rec msg |
peerName = 'proxy.tuwien.ac.at' ifTrue: [ ^self noProxy ].
message = #('robots' 'txt') ifTrue: [ ^self robots ].
rec := self objectFromString: (message at: 1).
msg := ((message at: 2), ':') asSymbol.
'HTML Reply' = ((rec class whichClassIncludesSelector: msg)
whichCategoryIncludesSelector: msg)
ifFalse: [ self error: 'Illegal message.' ].
rec perform: msg with: self.
self reply: '
Erzeugt vom Squeak WebServer am ';
reply: (Date today asString);
reply: ' um ';
reply: (Time now asString);
reply: '.