Class: Rack::Webconsole::Repl

Inherits:
Object
  • Object
show all
Defined in:
lib/rack/webconsole/repl.rb

Overview

Repl is a Rack middleware acting as a Ruby evaluator application.

In a nutshell, it evaluates a string in a Sandbox instance stored in an evil global variable. Then, to keep the state, it inspects the local variables and stores them in an instance variable for further retrieval.

Instance Method Summary (collapse)

Constructor Details

- (Repl) initialize(app)

Honor the Rack contract by saving the passed Rack application in an ivar.

Parameters:

  • app (Rack::Application)

    the previous Rack application in the middleware chain.



16
17
18
# File 'lib/rack/webconsole/repl.rb', line 16

def initialize(app)
  @app = app
end

Instance Method Details

- (Array) call(env)

Evaluates a string as Ruby code and returns the evaluated result as JSON.

It also stores the Sandbox state in a `$sandbox` global variable, with its local variables.

Parameters:

  • env (Hash)

    the Rack request environment.

Returns:

  • (Array)

    a Rack response with status code 200, HTTP headers and the evaluated Ruby result.



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/rack/webconsole/repl.rb', line 29

def call(env)
  status, headers, response = @app.call(env)

  req = Rack::Request.new(env)

  params = req.params

  result = begin
    $sandbox ||= Sandbox.new

    boilerplate = local_variables + [:ls]

    result = $sandbox.instance_eval """
      result = (#{params['query']})
      ls = (local_variables - #{boilerplate})
      @locals ||= {}
      @locals.update(ls.inject({}) do |hash, value|
        hash.update({value => eval(value.to_s)})
      end)
      result
    """

    result.inspect
  rescue=>e
    "Error: " + e.message
  end
  response_body = {:result => result}.to_json
  headers = {}
  headers['Content-Type'] = 'application/json'
  headers['Content-Length'] = response_body.length.to_s
  [200, headers, [response_body]]
end