help-smalltalk
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Help-smalltalk] How to restart an image running a server?


From: Paolo Bonzini
Subject: Re: [Help-smalltalk] How to restart an image running a server?
Date: Thu, 05 Oct 2006 11:24:00 +0200
User-agent: Thunderbird 1.5.0.7 (Macintosh/20060909)


Nah, let's make it a TODO and I am happy :-)
The real FIXME was the comment on using #parseTimestamp: (a method which is in fact unused and was *calling* for a wrapper). So, here is my take on your patch (only the WebServer.st hunks), which adds and uses a #dateTimeAt:ifAbsent: method.

Thanks, it was cool to see again a WebServer up and running on Darwin.

Paolo
--- orig/net/httpd/WebServer.st
+++ mod/net/httpd/WebServer.st
@@ -148,7 +148,7 @@ HTTP request using the Basic authenticat
 version
     | number |
     Version isNil ifFalse: [ ^Version ].
-    number := Smalltalk version substrings
+    number := Smalltalk version subStrings
        detect: [ :each | (each at: 1) isDigit ]
        ifNone: [ '0.0' "???" ].
 
@@ -229,6 +229,12 @@ log: req time: time
     self server log: req action uri: req location time: time.
 ! !
 
+Servlet class methodsFor: 'instance creation'!
+
+named: aString
+    ^(self new) name: aString; yourself
+! !
+
 
 !Servlet methodsFor: 'accessing'!
 
@@ -369,8 +375,9 @@ respondTo: aRequest
 
 notModified
     | ifModSince modTime |
-    ifModSince := request at: #'IF-MODIFIED-SINCE' ifAbsent: [ nil ].
-    ^ifModSince notNil and: [ self modifiedTime <= ifModSince ]!
+    ifModSince := request dateTimeAt: #'IF-MODIFIED-SINCE' ifAbsent: [ nil ].
+    modTime := self modifiedTime.
+    ^ifModSince notNil and: [ modTime <= ifModSince ]!
 
 request
     ^request!
@@ -589,6 +596,19 @@ at: aSymbol
 at: aSymbol ifAbsent: aBlock
     ^clientData at: aSymbol ifAbsent: aBlock!
 
+at: aSymbol ifPresent: aBlock
+    ^clientData at: aSymbol ifPresent: aBlock!
+
+dateTimeAt: aSymbol
+    ^self parseTimestamp: (clientData at: aSymbol)!
+
+dateTimeAt: aSymbol ifAbsent: aBlock
+    ^self parseTimestamp: (clientData at: aSymbol ifAbsent: [ ^aBlock value ])!
+
+dateTimeAt: aSymbol ifPresent: aBlock
+    ^clientData at: aSymbol ifPresent: [ :value |
+       aBlock value: (self parseTimestamp: value) ]!
+
 enumeratePostData: aBlock
     postData keysAndValuesDo: aBlock!
 
@@ -603,10 +623,21 @@ getRequest
     stream next.                               "Get nl"
 
     self extractClientData: version.
-    (action sameAs: 'POST') ifTrue: [ self extractPostData: version ].
-    
+               
+    (action sameAs: 'POST') ifTrue: [
+       self 
+           extractPostData: version 
+           contentLength: (clientData at: #'CONTENT-LENGTH' ifAbsent: [ nil ])
+    ].
+
     "Get back to binary mode"
-    stream := saveStream!
+    stream := saveStream.!
+
+hasPostData
+    ^postData notEmpty!
+
+postDataAt: aSymbol ifPresent: aBlock
+    ^postData at: aSymbol ifPresent: aBlock!
 
 location
     ^location!
@@ -620,35 +651,6 @@ originator
 pageFollows
     WebResponse new respondTo: self!
 
-parseTimestamp: ts
-    | tok d m y time |
-    tok := ts substrings.
-    (tok at: 1) last = $, ifFalse: [ "asctime:  Sun Nov  6 08:49:37 1994"
-         ts size = 5 ifFalse: [ ^nil ].
-         m := (ts at: 2) asSymbol.
-         d := (ts at: 3) asInteger.
-         y := (ts at: 5) asInteger.
-         time := ts at: 4.
-         ^self makeTimestamp: d month: m year: y time: time
-    ].
-    (tok at: 1) size = 4 ifTrue: [ "RFC 822:  Sun, 06 Nov 1994 08:49:37 GMT"
-         ts size = 6 ifFalse: [ ^nil ].
-         d := (ts at: 2) asInteger.
-         m := (ts at: 3) asSymbol.
-         y := (ts at: 4) asInteger.
-         time := ts at: 5.
-         ^self makeTimestamp: d month: m year: y time: time
-    ].
-    "RFC 850 (obsolete):  Sunday, 06-Nov-94 08:49:37 GMT"
-    ts size = 4 ifFalse: [ ^nil ].
-    d := ts at: 2.
-    time := ts at: 3.
-    d size = 9 ifFalse: [ ^nil ].
-    y := (d at: 8) base10DigitValue * 10 + (d at: 9) base10DigitValue + 1900.
-    m := (d copyFrom: 4 to: 6) asSymbol.
-    d := (d at: 1) base10DigitValue * 10 + (d at: 2) base10DigitValue.
-    ^self makeTimestamp: d month: m year: y time: time!
-
 moreRequests
     ^(self at: #Connection) sameAs: 'keep-alive'
 !
@@ -694,20 +696,51 @@ release
 
 !WebRequest methodsFor: 'private'!
 
-at: aSymbol put: aValue
-    ^clientData at: aSymbol put: aValue!
+parseTimestamp: ts
+    | tok d m y time |
+    tok := ts subStrings.
+    (tok at: 1) last = $, ifFalse: [ "asctime:  Sun Nov  6 08:49:37 1994"
+         ts size = 5 ifFalse: [ ^nil ].
+         m := (ts at: 2) asSymbol.
+         d := (ts at: 3) asInteger.
+         y := (ts at: 5) asInteger.
+         time := ts at: 4.
+         ^self makeTimestamp: d month: m year: y time: time
+    ].
+    (tok at: 1) size = 4 ifTrue: [ "RFC 822:  Sun, 06 Nov 1994 08:49:37 GMT"
+         ts size = 6 ifFalse: [ ^nil ].
+         d := (ts at: 2) asInteger.
+         m := (ts at: 3) asSymbol.
+         y := (ts at: 4) asInteger.
+         time := ts at: 5.
+         ^self makeTimestamp: d month: m year: y time: time
+    ].
+    "RFC 850 (obsolete):  Sunday, 06-Nov-94 08:49:37 GMT"
+    ts size = 4 ifFalse: [ ^nil ].
+    d := ts at: 2.
+    time := ts at: 3.
+    d size = 9 ifFalse: [ ^nil ].
+    y := (d at: 8) base10DigitValue * 10 + (d at: 9) base10DigitValue + 1900.
+    m := (d copyFrom: 4 to: 6) asSymbol.
+    d := (d at: 1) base10DigitValue * 10 + (d at: 2) base10DigitValue.
+    ^self makeTimestamp: d month: m year: y time: time!
 
 makeTimestamp: d month: m year: y time: t
-    | month |
+    | month sec |
     t size = 8 ifFalse: [ ^nil ].
 
     month := #(#Jan #Feb #Mar #Apr #May #Jun #Jul #Aug #Sep #Oct #Nov #Dec)
        indexOf: m ifAbsent: [ ^nil ].
 
-    ^(((t at: 1) base10DigitValue * 10 + (t at: 2) base10DigitValue) * 3600)
-     + (((t at: 4) base10DigitValue * 10 + (t at: 5) base10DigitValue) * 60)
-     + (((t at: 7) base10DigitValue * 10 + (t at: 8) base10DigitValue))
-     + (Date newDay: d monthIndex: month year: y) asSeconds!
+    sec :=
+       (((t at: 1) base10DigitValue * 10 + (t at: 2) base10DigitValue) * 3600)
+      + (((t at: 4) base10DigitValue * 10 + (t at: 5) base10DigitValue) * 60)
+      + (((t at: 7) base10DigitValue * 10 + (t at: 8) base10DigitValue)).
+
+    ^(DateTime newDay: d monthIndex: month year: y) addSeconds: sec!
+
+at: aSymbol put: aValue
+    ^clientData at: aSymbol put: aValue!
 
 endOfLine
     ^EndOfLine!
@@ -734,28 +767,36 @@ extractClientData: clientVersion
 
 extractLocation
     uri := (stream upToAll: 'HTTP/') trimSeparators.
-    location := uri substrings: $?.
+    location := uri subStrings: $?.
+       location isEmpty ifTrue:
+               [ self error: 'Empty uri: ', uri, '.' ].
     location size = 2 ifTrue: [ self extractQueryData: (location at: 2) ].
-    location := (location at: 1) substrings: $/.
+    location := (location at: 1) subStrings: $/.
     location := location collect: [:each | (URL decode: each) ].
     location := location reject: [:each | each isEmpty ]!
 
-extractPostData: clientVersion
+extractPostData: clientVersion contentLength: contentLength
+    | s |
     clientVersion ~= '1.0'
-       ifTrue: [ stream nextPut: 'HTTP/1.1 100 Continue'; nl; nl ].
+       ifTrue: [ stream nextPutAll: 'HTTP/1.1 100 Continue'; nl; nl ].
 
     (self at: #'CONTENT-TYPE' ifAbsent: [ nil ]) ~=
-       'application/x-www-form-urlencoded' ifTrue: [ ^self ].
-
-    ^self extractQueryData: (stream upTo: Character cr)!
+               'application/x-www-form-urlencoded' ifTrue: [ ^self ].
+       
+    "TODO: Parse the stream directly, rather than loading it all into 
+    memory, because it could be large."
+    s := contentLength notNil 
+       ifTrue: [ stream next: contentLength asInteger ]
+       ifFalse: [ stream upTo: Character cr ].
+       
+    ^self extractQueryData: s!
 
 extractQueryData: query
-    (query substrings: $&) do: [ :each || pair |
-       pair := each substrings: $=.
+    (query subStrings: $&) do: [ :each || pair |
+       pair := each subStrings: $=.
        self
            postDataAt: (URL decode: pair first) asSymbol
-           put: (URL decode: pair last)
-    ]!
+           put: (URL decode: (pair at: 2 ifAbsent: [ '' ])) ]!
 
 postDataAt: aSymbol put: aValue
     ^postData at: aSymbol put: aValue! !

reply via email to

[Prev in Thread] Current Thread [Next in Thread]