Very cool. btw, does the Zinc HTTPS handle client-certificates? That
might be reasonably secure if a private tunnel to the box is not available.
cheers -ben
Sven Van Caekenberghe wrote:
Hi,
Here is a little tool that might be useful to some you. For others it might be
a nice example.
So you have your shiny Pharo server application running in the cloud. When
something goes wrong, most of the time you will just restart, manually or
automatically. But sometimes you wish you could interact with a running
headless server image. Problem is, you can't out of the box.
ZnReadEvalPrintDelegate is a simple tool that exports a REPL Web Service. Much
like the emergency evaluator. Primitive but better than nothing. Install it on
a port of your choice, running in a independent Zn HTTP server, bound to
localhost only.
ZnReadEvalPrintDelegate startInServerOn: 1701.
There is only one API method: POST a plain/text Smalltalk expression to
evaluate, get the result back.
ZnClient new
url: 'http://localhost:1701/repl';
contents: '42 factorial';
post.
Here is an example terminal session (logged in to the server, not remote):
A GET on the service /repl gives some help text
$ curl http://localhost:1701/repl
# Pharo Smalltalk REPL. POST expressions to evaluate
# Here is one way (type ctrl-d to end input)
curl -X POST -H'Content-Type:text/plain' --data-binary @-
http://localhost:1701/repl
A POST with -d is good for short expressions
$ curl -X POST -H'Content-Type:text/plain' -d '42 factorial'
http://localhost:1701/repl
1405006117752879898543142606244511569936384000000000
For longer or multi line expressions you can read input from stdin and end with
ctrl-d (copy the expression returned by the GET). Or you could send text files.
$ curl -X POST -H'Content-Type:text/plain' --data-binary @-
http://localhost:1701/repl
{ (1 to: 10) sum. (1 to: 10) average }
{55. (11/2)}
There is error handling as well:
$ curl -X POST -H'Content-Type:text/plain' --data-binary @-
http://localhost:1701/repl
1 plus: 2
MessageNotUnderstood: SmallInteger>>plus:
SmallInteger(Object)>>doesNotUnderstand: #plus:
Receiver: 1
Arguments and temporary variables:
aMessage: plus: 2
exception: MessageNotUnderstood: SmallInteger>>plus:
resumeValue: nil
Receiver's instance variables:
1
UndefinedObject>>DoIt
Compiler>>evaluate:in:to:notifying:ifFail:logged:
Compiler>>evaluate:in:to:notifying:ifFail:
Compiler>>evaluate:in:to:
ZnReadEvalPrintDelegate>>evaluate: in Block: [| result |...
BlockClosure>>on:do:
ZnReadEvalPrintDelegate>>evaluate: in Block: [:out | [| result |...
String class(SequenceableCollection class)>>new:streamContents:
WARNING: never open this service beyond your local network ! This service gives
you absolute control over and access to everything in your image. For example,
the following will kill your image:
$ curl -X POST -H'Content-Type:text/plain' -d 'Smalltalk quitPrimitive'
http://localhost:1701/repl
All this in one class and a handful of methods.
Enjoy,
Sven
PS1: Part of Zinc HTTP Components, in the bleedingEdge version.
PS2: Of course, basic authentication or HTTPS can be added through simple Zn
configuration.
--
Sven Van Caekenberghe
Proudly supporting Pharo
http://pharo.org
http://association.pharo.org
http://consortium.pharo.org