class RackConsole

Constants

VERSION
VIEW_TEMPLATE

Public Class Methods

new(_binding = binding, storage: ->(env){ CookieScriptStorage.new env } click to toggle source
# File lib/rack_web_console.rb, line 11
def initialize(_binding = binding, storage: ->(env){ CookieScriptStorage.new env }, token: nil)
  @storage, @binding = storage, _binding
  @@token ||= token || SecureRandom.base64(32)
end

Public Instance Methods

call(env) click to toggle source
# File lib/rack_web_console.rb, line 16
def call(env)
  @_storage = ::Proc === @storage ? @storage[env] : @storage
  env['REQUEST_METHOD'] == 'POST' ? process_script(env) : render_view(env)
end

Private Instance Methods

domain_from(referer) click to toggle source
# File lib/rack_web_console.rb, line 50
def domain_from(referer)
  referer && referer.gsub(%r{(?:\Ahttps?://|/.*)}, '')
end
process_script(env) click to toggle source
# File lib/rack_web_console.rb, line 23
def process_script(env)
  params = CGI.parse env['rack.input'].read
  token = params['token']&.first.to_s
  return [403, {}, []] unless same_origin?(env) && token == @@token
  script = params['script'].first
  @_storage&.script=(script)
  result = []
  (oc = OutputCapture.new).capture do
    begin
      result_eval = eval script, @binding
      result << %Q{<div class="stdout">#{::ERB::Util.h oc.output}</div>}
      result << %Q{<div class="return">#{::ERB::Util.h result_eval.inspect}</div>}
    rescue ::Exception => e
      message = ::ERB::Util.h "#{e.message}\n#{e.backtrace.join "\n"}"
      result << %Q{<div class="stdout">#{::ERB::Util.h oc.output}</div>}
      result << %Q{<div class="error">#{message}</div>}
    end
  end
  headers = { 'Content-Type' => 'text/html; charset=utf-8' }
  @_storage.set_cookie_header! headers
  [ 200, headers, [ result.join("\n") ] ]
end
render_view(env) click to toggle source
# File lib/rack_web_console.rb, line 54
def render_view(env)
  [ 200, { 'Content-Type' => 'text/html; charset=utf-8' }, [ view_response(env) ] ]
end
same_origin?(env) click to toggle source
# File lib/rack_web_console.rb, line 46
def same_origin?(env)
  env['HTTP_HOST'] == (domain_from(env['HTTP_ORIGIN']) || domain_from(env['HTTP_REFERER']))
end
view_response(env) click to toggle source
# File lib/rack_web_console.rb, line 58
def view_response(env)
  script = (s = @_storage&.script) ? ::ERB::Util.h(s) : ''
  token = @@token
  ::ERB.new(::File.read view_template).result binding
end
view_template() click to toggle source
# File lib/rack_web_console.rb, line 64
def view_template # so that it could be easily subclassed and overriden:
  VIEW_TEMPLATE
end