a http server and mini-web-framework in Slate
Clean URL parsing now works for more than one url arg. Examples:
/hello/Alex/page/2 => method #hello:page: with {'Alex'. '2'}. /hello/Alex/blah => method #hellp:page: with {'Alex'. True}.
h@(Hello traits) hello &name: name
[ 'Hello, ' ; name printString ; '!' ].
[ | segments method targets |
[ | pathAndQuery segments queries method targets |
segments: (r uri splitWith: $/).
(segments length isZero)
ifTrue: [ method: 'index'.
targets: {s controller}. ]
ifFalse: [ (segments length = 1)
ifTrue: [ method: segments first.
targets: {s controller}. ]
ifFalse: [ method: (segments first) ; ':'. "TODO: Make this work for more than one url segment."
targets: {s controller. segments second}. ] ].
pathAndQuery: (r uri splitWith: $?).
segments: ((pathAndQuery at: 0) splitWith: $/).
queries: {}.
inform: 'Segments: ' ; segments printString.
(pathAndQuery length > 1)
ifTrue: [
queries: ((pathAndQuery at: 1) splitWith: $&).
queries: (queries gather: [ | :acc :query split option |
split: (query splitWith: $=).
option: ('&' ; (split at: 0) ; ':') intern.
acc ; ((split length = 1)
ifTrue: [{option. True}]
ifFalse: [{option. split at: 1}])
] &initial: {}).
].
inform: 'Queries: ' ; queries printString.
targets: {s controller}.
segments length caseOf: {
0 -> [ method: 'index'. ].
1 -> [ method: segments first. ]
} otherwise: [ | segmentReader |
method: ''.
segmentReader: segments reader.
[segmentReader isAtEnd]
whileFalse: [
method: method ; (segmentReader next) ; ':'.
(segmentReader isAtEnd)
ifTrue: [ targets: targets ; {True}. ]
ifFalse: [ targets: targets ; {segmentReader next}. ].
].
].
inform: 'Method: ' ; method intern printString.
inform: 'Targets: ' ; targets printString.
body: ((method intern) sendTo: targets). ]).
body: ((method intern) sendTo: targets &optionals: queries). ]).
[ port `defaultsTo: 8080.
s controller: c.
[ s controller: c.