[racket] Limiting net-repl provided functions
10 minutes ago, Jukka Tuominen wrote:
>
> > -----Original Message-----
> > From: Eli Barzilay [mailto:eli at barzilay.org]
> > Sent: 28 June 2011 09:45
> > To: Jukka Tuominen
> > Cc: Sam Tobin-Hochstadt; users at racket-lang.org
> > Subject: RE: [racket] Limiting net-repl provided functions
> >
> >
> > About a minute ago, Jukka Tuominen wrote:
> > >
> > > > The sandbox is working in an isolated world (by design, of
> > > > course), so you need to do the (require "sb-functions.rkt") inside
> > > > the sandbox. For example, just use (sb-eval '(require ...)).
> > >
> > > Wouldn't that mean that the sb-evaluator has to be first initiated
> > > to understand 'require' plus many other primitives, not just the
> > > intented f1, f2, f3?
> >
> > Yes.
> >
> >
> > > Is this even possible?
> >
> > Yes. You can get that with
> >
> > (make-evaluator 'racket/base)
>
> Sorry, I meant to say that is it possible to have only the f1, f2, and f3
> provided, but not even 'require'...
> >
> > If you want a limited language, then you can make up a language with
> > `require' and the limited set of bindings you want in. If you also
> > don't want `require' in the language, you can make the language itself
> > provide the functions that you want to make public, but not `require'
> > itself. Yet another option is to use `call-in-sandbox-context' with
> > `namespace-require'.
>
> yes, I want to have a more limited language, yet without leaving the
> comfort of Racket, meaning that on the server side you have all the
> familiar tools to create new 'primitives', and on the client side,
> use these primitives just like any other, no matter how and where
> they take place.
So that's what you need to do. Here's an example:
---- limited.rkt ---
#lang racket/base
(provide
;; special things
#%app #%module-begin #%datum #%top #%top-interaction
;; visible primitives
+ - quote length
;; additional functions
f1)
;; definitions for the additional functions
(define (f1 l) (length l))
and then:
> (require racket/sandbox)
> (define e (make-evaluator "limited.rkt"))
> (e '(+ 1 2))
3
> (e '(- (f1 '(x y z)) 1))
2
and not much else works... Specifically, `require' is not there:
> (e '(require racket))
reference to an identifier before its definition: require in module:
"program"
> > (All of this is much more complicated then what Matthias
> > originally hinted at: if you know the set of functions that you
> > want to expose, then you can just dispatch on the input symbols
> > and call the corresponding function.)
>
> I wish I was just pretending not to see the obvious (sigh)... Yes
> please, I would very much like the obvious and simple solution! :)
> Not just for me, but also for the ones that hopefully will end up
> creating these new services eventually. Even the hint 2 isn't enough
> for me unfortunately (sigh 2)...
Just something like this:
(require "server-functions.rkt")
(define request (read from-client))
(unless (and (list? request) (pair? request) (symbol? (car request)))
;; or use `match' instead
(throw-error-to-port to-client "bad request"))
(apply (case (car request)
[(f1) f1]
[(f2) f2]
... more here ...)
(cdr request))
--
((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:
http://barzilay.org/ Maze is Life!