# class WebConsole::Middleware

### Constants

TEMPLATES_PATH

### Public Class Methods

new(app) click to toggle source

    # File lib/web_console/middleware.rb, line 13
    def initialize(app)
      @app = app
    end

### Public Instance Methods

call(env) click to toggle source

    # File lib/web_console/middleware.rb, line 17
    def call(env)
      app_exception = catch :app_exception do
        request = create_regular_or_whiny_request(env)
        return call_app(env) unless request.from_whitelisted_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 = call_app(env)

        if session = Session.from(Thread.current) and acceptable_content_type?(headers)
          response = Response.new(body, status, headers)
          template = Template.new(env, session)

          response.headers["X-Web-Console-Session-Id"] = session.id
          response.headers["X-Web-Console-Mount-Point"] = mount_point
          response.write(template.render('index'))
          response.finish
        else
          [ status, headers, body ]
        end
      end
    rescue => e
      WebConsole.logger.error("\n#{e.class}: #{e}\n\tfrom #{e.backtrace.join("\n\tfrom ")}")
      raise e
    ensure
      # Clean up the fiber locals after the session creation. Object#console
      # uses those to communicate the current binding or exception to the middleware.
      Thread.current[:__web_console_exception] = nil
      Thread.current[:__web_console_binding] = nil

      raise app_exception if Exception === app_exception
    end

### Private Instance Methods

acceptable_content_type?(headers) click to toggle source

    # File lib/web_console/middleware.rb, line 56
    def acceptable_content_type?(headers)
      Mime::Type.parse(headers['Content-Type']).first == Mime[:html]
    end

binding_change_re() click to toggle source

    # File lib/web_console/middleware.rb, line 88
    def binding_change_re
      @_binding_change_re ||= %r{#{repl_sessions_re}/trace\z}
    end

call_app(env) click to toggle source

    # File lib/web_console/middleware.rb, line 130
    def call_app(env)
      @app.call(env)
    rescue => e
      throw :app_exception, e
    end

change_stack_trace(id, request) click to toggle source

    # File lib/web_console/middleware.rb, line 110
    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

create_regular_or_whiny_request(env) click to toggle source

    # File lib/web_console/middleware.rb, line 75
    def create_regular_or_whiny_request(env)
      request = Request.new(env)
      whiny_requests ? WhinyRequest.new(request) : request
    end

id_for_repl_session_stack_frame_change(request) click to toggle source

    # File lib/web_console/middleware.rb, line 98
    def id_for_repl_session_stack_frame_change(request)
      if request.xhr? && request.post?
        binding_change_re.match(request.path) { |m| m[:id] }
      end
    end

id_for_repl_session_update(request) click to toggle source

    # File lib/web_console/middleware.rb, line 92
    def id_for_repl_session_update(request)
      if request.xhr? && request.put?
        update_re.match(request.path) { |m| m[:id] }
      end
    end

json_response(opts = {}) { || ... } click to toggle source

    # File lib/web_console/middleware.rb, line 60
    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

json_response_with_session(id, request, opts = {}) { |session| ... } click to toggle source

    # File lib/web_console/middleware.rb, line 68
    def json_response_with_session(id, request, opts = {})
      return respond_with_unacceptable_request unless request.acceptable?
      return respond_with_unavailable_session(id) unless session = Session.find(id)

      json_response(opts) { yield session }
    end

repl_sessions_re() click to toggle source

    # File lib/web_console/middleware.rb, line 80
    def repl_sessions_re
      @_repl_sessions_re ||= %r{#{mount_point}/repl_sessions/(?<id>[^/]+)}
    end

respond_with_unacceptable_request() click to toggle source

    # File lib/web_console/middleware.rb, line 124
    def respond_with_unacceptable_request
      json_response(status: 406) do
        { output: I18n.t('errors.unacceptable_request') }
      end
    end

respond_with_unavailable_session(id) click to toggle source

    # File lib/web_console/middleware.rb, line 118
    def respond_with_unavailable_session(id)
      json_response(status: 404) do
        { output: format(I18n.t('errors.unavailable_session'), id: id)}
      end
    end

update_re() click to toggle source

    # File lib/web_console/middleware.rb, line 84
    def update_re
      @_update_re ||= %r{#{repl_sessions_re}\z}
    end

update_repl_session(id, request) click to toggle source

    # File lib/web_console/middleware.rb, line 104
    def update_repl_session(id, request)
      json_response_with_session(id, request) do |session|
        { output: session.eval(request.params[:input]) }
      end
    end