/usr/lib/ruby/vendor_ruby/web_console/middleware.rb is in ruby-web-console 2.2.1-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 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 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | require 'active_support/core_ext/string/strip'
module WebConsole
class Middleware
TEMPLATES_PATH = File.expand_path('../templates', __FILE__)
DEFAULT_OPTIONS = {
update_re: %r{/repl_sessions/(?<id>.+?)\z},
binding_change_re: %r{/repl_sessions/(?<id>.+?)/trace\z}
}
UNAVAILABLE_SESSION_MESSAGE = <<-END.strip_heredoc
Session %{id} is is no longer available in memory.
If you happen to run on a multi-process server (like Unicorn) the process
this request hit doesn't store %{id} in memory.
END
UNACCEPTABLE_REQUEST_MESSAGE = "A supported version is expected in the Accept header."
cattr_accessor :whiny_requests
@@whiny_requests = true
def initialize(app, options = {})
@app = app
@options = DEFAULT_OPTIONS.merge(options)
end
def call(env)
request = create_regular_or_whiny_request(env)
return @app.call(env) unless request.from_whitelited_ip?
if id = id_for_repl_session_update(request)
return update_repl_session(id, request)
elsif id = id_for_repl_session_stack_frame_change(request)
return change_stack_trace(id, request)
end
status, headers, body = @app.call(env)
if exception = env['web_console.exception']
session = Session.from_exception(exception)
elsif binding = env['web_console.binding']
session = Session.from_binding(binding)
end
if session && request.acceptable_content_type?
headers["X-Web-Console-Session-Id"] = session.id
response = Rack::Response.new(body, status, headers)
template = Template.new(env, session)
response.write(template.render('index'))
response.finish
else
[ status, headers, body ]
end
end
private
def json_response(opts = {})
status = opts.fetch(:status, 200)
headers = { 'Content-Type' => 'application/json; charset = utf-8' }
body = yield.to_json
Rack::Response.new(body, status, headers).finish
end
def json_response_with_session(id, request, opts = {})
json_response(opts) do
unless request.acceptable?
return respond_with_unacceptable_request
end
unless session = Session.find(id)
return respond_with_unavailable_session(id)
end
yield session
end
end
def create_regular_or_whiny_request(env)
request = Request.new(env)
whiny_requests ? WhinyRequest.new(request) : request
end
def update_re
@options[:update_re]
end
def binding_change_re
@options[:binding_change_re]
end
def id_for_repl_session_update(request)
if request.xhr? && request.put?
update_re.match(request.path_info) { |m| m[:id] }
end
end
def id_for_repl_session_stack_frame_change(request)
if request.xhr? && request.post?
binding_change_re.match(request.path_info) { |m| m[:id] }
end
end
def update_repl_session(id, request)
json_response_with_session(id, request) do |session|
{ output: session.eval(request.params[:input]) }
end
end
def change_stack_trace(id, request)
json_response_with_session(id, request) do |session|
session.switch_binding_to(request.params[:frame_id])
{ ok: true }
end
end
def respond_with_unavailable_session(id)
json_response(status: 404) do
{ output: format(UNAVAILABLE_SESSION_MESSAGE, id: id)}
end
end
def respond_with_unacceptable_request
json_response(status: 406) do
{ error: UNACCEPTABLE_REQUEST_MESSAGE }
end
end
end
end
|