meta_request 0.2.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of meta_request might be problematic. Click here for more details.
- data/.gitignore +17 -0
- data/Gemfile +9 -0
- data/LICENSE.txt +22 -0
- data/README.md +49 -0
- data/Rakefile +11 -0
- data/lib/meta_request/app_notifications.rb +32 -0
- data/lib/meta_request/app_request.rb +19 -0
- data/lib/meta_request/event.rb +63 -0
- data/lib/meta_request/log_interceptor.rb +49 -0
- data/lib/meta_request/middlewares/app_request_handler.rb +28 -0
- data/lib/meta_request/middlewares/headers.rb +30 -0
- data/lib/meta_request/middlewares/meta_request_handler.rb +25 -0
- data/lib/meta_request/middlewares/request_id.rb +42 -0
- data/lib/meta_request/middlewares.rb +8 -0
- data/lib/meta_request/railtie.rb +24 -0
- data/lib/meta_request/storage.rb +43 -0
- data/lib/meta_request/version.rb +3 -0
- data/lib/meta_request.rb +15 -0
- data/meta_request.gemspec +23 -0
- data/test/meta_request/app_notifications_test.rb +33 -0
- data/test/meta_request/event_test.rb +34 -0
- data/test/meta_request/log_interceptor_test.rb +22 -0
- data/test/meta_request/middlewares/meta_request_handler_test.rb +38 -0
- data/test/meta_request/storage_test.rb +26 -0
- data/test/test_helper.rb +11 -0
- metadata +124 -0
    
        data/.gitignore
    ADDED
    
    
    
        data/Gemfile
    ADDED
    
    
    
        data/LICENSE.txt
    ADDED
    
    | @@ -0,0 +1,22 @@ | |
| 1 | 
            +
            Copyright (c) 2012 Dejan Simic
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            MIT License
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            Permission is hereby granted, free of charge, to any person obtaining
         | 
| 6 | 
            +
            a copy of this software and associated documentation files (the
         | 
| 7 | 
            +
            "Software"), to deal in the Software without restriction, including
         | 
| 8 | 
            +
            without limitation the rights to use, copy, modify, merge, publish,
         | 
| 9 | 
            +
            distribute, sublicense, and/or sell copies of the Software, and to
         | 
| 10 | 
            +
            permit persons to whom the Software is furnished to do so, subject to
         | 
| 11 | 
            +
            the following conditions:
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            The above copyright notice and this permission notice shall be
         | 
| 14 | 
            +
            included in all copies or substantial portions of the Software.
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
         | 
| 17 | 
            +
            EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
         | 
| 18 | 
            +
            MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
         | 
| 19 | 
            +
            NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
         | 
| 20 | 
            +
            LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
         | 
| 21 | 
            +
            OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
         | 
| 22 | 
            +
            WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
         | 
    
        data/README.md
    ADDED
    
    | @@ -0,0 +1,49 @@ | |
| 1 | 
            +
            # MetaRequest
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            Supporting gem for [Rails Panel (Google Chrome extension for Rails development)](https://github.com/dejan/rails_panel).
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            ## Installation
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            Add meta_request gem to development group in Gemfile:
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            ```ruby
         | 
| 10 | 
            +
            group :development do
         | 
| 11 | 
            +
              gem 'meta_request'
         | 
| 12 | 
            +
            end
         | 
| 13 | 
            +
            ```
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            ## Usage
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            See [Rails Panel extension](https://github.com/dejan/rails_panel).
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            ## Compatibility Warnings
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            If you're using [LiveReload](http://livereload.com/) or
         | 
| 22 | 
            +
            [Rack::LiveReload](https://github.com/johnbintz/rack-livereload) make sure to
         | 
| 23 | 
            +
            exclude watching your tmp/ folder because meta_request writes a lot of data there
         | 
| 24 | 
            +
            and your browser will refresh like a madman.
         | 
| 25 | 
            +
             | 
| 26 | 
            +
            ## Licence
         | 
| 27 | 
            +
             | 
| 28 | 
            +
            Copyright (c) 2012 Dejan Simic
         | 
| 29 | 
            +
             | 
| 30 | 
            +
            MIT License
         | 
| 31 | 
            +
             | 
| 32 | 
            +
            Permission is hereby granted, free of charge, to any person obtaining
         | 
| 33 | 
            +
            a copy of this software and associated documentation files (the
         | 
| 34 | 
            +
            "Software"), to deal in the Software without restriction, including
         | 
| 35 | 
            +
            without limitation the rights to use, copy, modify, merge, publish,
         | 
| 36 | 
            +
            distribute, sublicense, and/or sell copies of the Software, and to
         | 
| 37 | 
            +
            permit persons to whom the Software is furnished to do so, subject to
         | 
| 38 | 
            +
            the following conditions:
         | 
| 39 | 
            +
             | 
| 40 | 
            +
            The above copyright notice and this permission notice shall be
         | 
| 41 | 
            +
            included in all copies or substantial portions of the Software.
         | 
| 42 | 
            +
             | 
| 43 | 
            +
            THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
         | 
| 44 | 
            +
            EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
         | 
| 45 | 
            +
            MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
         | 
| 46 | 
            +
            NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
         | 
| 47 | 
            +
            LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
         | 
| 48 | 
            +
            OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
         | 
| 49 | 
            +
            WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
         | 
    
        data/Rakefile
    ADDED
    
    
| @@ -0,0 +1,32 @@ | |
| 1 | 
            +
            module MetaRequest
         | 
| 2 | 
            +
              class AppNotifications
         | 
| 3 | 
            +
             | 
| 4 | 
            +
                # Subscribe to all events relevant to RailsPanel
         | 
| 5 | 
            +
                #
         | 
| 6 | 
            +
                def self.subscribe
         | 
| 7 | 
            +
                  new.
         | 
| 8 | 
            +
                    subscribe("meta_request.log").
         | 
| 9 | 
            +
                    subscribe("sql.active_record").
         | 
| 10 | 
            +
                    subscribe("render_partial.action_view").
         | 
| 11 | 
            +
                    subscribe("render_template.action_view").
         | 
| 12 | 
            +
                    subscribe("process_action.action_controller.exception").
         | 
| 13 | 
            +
                    subscribe("process_action.action_controller") do |*args|
         | 
| 14 | 
            +
                      name, start, ending, transaction_id, payload = args
         | 
| 15 | 
            +
                      payload[:format] ||= (payload[:formats]||[]).first # Rails 3.0.x Support
         | 
| 16 | 
            +
                      payload[:status] = '500' if payload[:exception]
         | 
| 17 | 
            +
                      Event.new(name, start, ending, transaction_id, payload)
         | 
| 18 | 
            +
                    end
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                def subscribe(event_name)
         | 
| 22 | 
            +
                  ActiveSupport::Notifications.subscribe(event_name) do |*args|
         | 
| 23 | 
            +
                    event = block_given?? yield(*args) : Event.new(*args)
         | 
| 24 | 
            +
                    AppRequest.current.events << event if AppRequest.current
         | 
| 25 | 
            +
                  end
         | 
| 26 | 
            +
                  self
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
            end
         | 
| 32 | 
            +
             | 
| @@ -0,0 +1,19 @@ | |
| 1 | 
            +
            module MetaRequest
         | 
| 2 | 
            +
              class AppRequest
         | 
| 3 | 
            +
                attr_reader :id, :events
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                def initialize(id)
         | 
| 6 | 
            +
                  @id = id
         | 
| 7 | 
            +
                  @events = []
         | 
| 8 | 
            +
                end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                def self.current
         | 
| 11 | 
            +
                  Thread.current[:meta_request_id]
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                def current!
         | 
| 15 | 
            +
                  Thread.current[:meta_request_id] = self
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
            end
         | 
| @@ -0,0 +1,63 @@ | |
| 1 | 
            +
            require 'active_support/json'
         | 
| 2 | 
            +
            require 'active_support/core_ext'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            module MetaRequest
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              # Subclass of ActiveSupport Event that is JSON encodable
         | 
| 7 | 
            +
              #
         | 
| 8 | 
            +
              class Event < ActiveSupport::Notifications::Event
         | 
| 9 | 
            +
                attr_reader :duration
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                def initialize(name, start, ending, transaction_id, payload)
         | 
| 12 | 
            +
                  super(name, start, ending, transaction_id, json_encodable(payload))
         | 
| 13 | 
            +
                  @duration = 1000.0 * (ending - start)
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                def self.events_for_exception(exception_wrapper)
         | 
| 17 | 
            +
                  if defined?(ActionDispatch::ExceptionWrapper)
         | 
| 18 | 
            +
                    exception = exception_wrapper.exception
         | 
| 19 | 
            +
                    trace = exception_wrapper.application_trace
         | 
| 20 | 
            +
                    trace = exception_wrapper.framework_trace if trace.empty?
         | 
| 21 | 
            +
                  else
         | 
| 22 | 
            +
                    exception = exception_wrapper
         | 
| 23 | 
            +
                    trace = exception.backtrace
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
                  trace.unshift "#{exception.class} (#{exception.message})"
         | 
| 26 | 
            +
                  trace.map do |call|
         | 
| 27 | 
            +
                    Event.new('process_action.action_controller.exception', 0, 0, nil, {:call => call})
         | 
| 28 | 
            +
                  end
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                private
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                def json_encodable(payload)
         | 
| 34 | 
            +
                  return {} unless payload.is_a?(Hash)
         | 
| 35 | 
            +
                  transform_hash(payload, :deep => true) { |hash, key, value|
         | 
| 36 | 
            +
                    begin
         | 
| 37 | 
            +
                      value.to_json(:methods => [:duration])
         | 
| 38 | 
            +
                      new_value = value
         | 
| 39 | 
            +
                    rescue
         | 
| 40 | 
            +
                      new_value = 'Not JSON Encodable'
         | 
| 41 | 
            +
                    end
         | 
| 42 | 
            +
                    hash[key] = new_value
         | 
| 43 | 
            +
                  }.with_indifferent_access
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                # https://gist.github.com/dbenhur/1070399
         | 
| 47 | 
            +
                def transform_hash(original, options={}, &block)
         | 
| 48 | 
            +
                  options[:safe_descent] ||= {}
         | 
| 49 | 
            +
                  new_hash = {}
         | 
| 50 | 
            +
                  options[:safe_descent][original.object_id] = new_hash
         | 
| 51 | 
            +
                  original.inject(new_hash) { |result, (key,value)|
         | 
| 52 | 
            +
                    if (options[:deep] && Hash === value)
         | 
| 53 | 
            +
                      value = options[:safe_descent].fetch( value.object_id ) {
         | 
| 54 | 
            +
                        transform_hash(value, options, &block)
         | 
| 55 | 
            +
                      }
         | 
| 56 | 
            +
                    end
         | 
| 57 | 
            +
                    block.call(result,key,value)
         | 
| 58 | 
            +
                    result
         | 
| 59 | 
            +
                  }
         | 
| 60 | 
            +
                end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
              end
         | 
| 63 | 
            +
            end
         | 
| @@ -0,0 +1,49 @@ | |
| 1 | 
            +
            require 'callsite'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module MetaRequest
         | 
| 4 | 
            +
              module LogInterceptor
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                def debug(message = nil, &block)
         | 
| 7 | 
            +
                  push_event(:debug, message)
         | 
| 8 | 
            +
                  super
         | 
| 9 | 
            +
                end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                def info(message = nil, &block)
         | 
| 12 | 
            +
                  push_event(:info, message)
         | 
| 13 | 
            +
                  super
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                def warn(message = nil, &block)
         | 
| 17 | 
            +
                  push_event(:warn, message)
         | 
| 18 | 
            +
                  super
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                def error(message = nil, &block)
         | 
| 22 | 
            +
                  push_event(:error, message)
         | 
| 23 | 
            +
                  super
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                def fatal(message = nil, &block)
         | 
| 27 | 
            +
                  push_event(:fatal, message)
         | 
| 28 | 
            +
                  super
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                def unknown(message = nil, &block)
         | 
| 32 | 
            +
                  push_event(:unknown, message)
         | 
| 33 | 
            +
                  super
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
                
         | 
| 36 | 
            +
                
         | 
| 37 | 
            +
                private
         | 
| 38 | 
            +
                def push_event(level, message)
         | 
| 39 | 
            +
                  dev_log = AppRequest.current && caller[1] =~ /#{Rails.root}/
         | 
| 40 | 
            +
                  if dev_log
         | 
| 41 | 
            +
                    c = Callsite.parse(caller[1])
         | 
| 42 | 
            +
                    payload = {:message => message, :level => level, :line => c.line, :filename => c.filename, :method => c.method}
         | 
| 43 | 
            +
                    AppRequest.current.events << Event.new('meta_request.log', 0, 0, 0, payload)
         | 
| 44 | 
            +
                  end
         | 
| 45 | 
            +
                rescue Exception => e
         | 
| 46 | 
            +
                  MetaRequest.logger.fatal(e.message + "\n " + e.backtrace.join("\n "))
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
              end
         | 
| 49 | 
            +
            end
         | 
| @@ -0,0 +1,28 @@ | |
| 1 | 
            +
            require 'json'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module MetaRequest
         | 
| 4 | 
            +
              module Middlewares
         | 
| 5 | 
            +
                class AppRequestHandler
         | 
| 6 | 
            +
                  def initialize(app)
         | 
| 7 | 
            +
                    @app = app
         | 
| 8 | 
            +
                  end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                  def call(env)
         | 
| 11 | 
            +
                    app_request = AppRequest.new env["action_dispatch.request_id"]
         | 
| 12 | 
            +
                    app_request.current!
         | 
| 13 | 
            +
                    @app.call(env)
         | 
| 14 | 
            +
                  rescue Exception => exception
         | 
| 15 | 
            +
                    if defined?(ActionDispatch::ExceptionWrapper)
         | 
| 16 | 
            +
                      wrapper = ActionDispatch::ExceptionWrapper.new(env, exception)
         | 
| 17 | 
            +
                      app_request.events.push(*Event.events_for_exception(wrapper))
         | 
| 18 | 
            +
                    else
         | 
| 19 | 
            +
                      app_request.events.push(*Event.events_for_exception(exception))
         | 
| 20 | 
            +
                    end
         | 
| 21 | 
            +
                    raise
         | 
| 22 | 
            +
                  ensure
         | 
| 23 | 
            +
                    Storage.new(app_request.id).write(app_request.events.to_json) unless app_request.events.empty?
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
              end
         | 
| 27 | 
            +
            end
         | 
| 28 | 
            +
             | 
| @@ -0,0 +1,30 @@ | |
| 1 | 
            +
            require 'rack/contrib/response_headers'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module MetaRequest
         | 
| 4 | 
            +
              module Middlewares
         | 
| 5 | 
            +
                class Headers
         | 
| 6 | 
            +
                  def initialize(app, app_config)
         | 
| 7 | 
            +
                    @app = app
         | 
| 8 | 
            +
                    @app_config = app_config
         | 
| 9 | 
            +
                  end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                  def call(env)
         | 
| 12 | 
            +
                    request_path = env['PATH_INFO']
         | 
| 13 | 
            +
                    middleware = Rack::ResponseHeaders.new(@app) do |headers|
         | 
| 14 | 
            +
                      headers['X-Meta-Request-Version'] = MetaRequest::VERSION unless asset?(request_path)
         | 
| 15 | 
            +
                    end
         | 
| 16 | 
            +
                    middleware.call(env)
         | 
| 17 | 
            +
                  end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                  private
         | 
| 20 | 
            +
                  def asset?(path)
         | 
| 21 | 
            +
                    @app_config.respond_to?(:assets) && path.start_with?(assets_prefix)
         | 
| 22 | 
            +
                  end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                  def assets_prefix
         | 
| 25 | 
            +
                    "/#{@app_config.assets.prefix[/\A\/?(.*?)\/?\z/, 1]}/"
         | 
| 26 | 
            +
                  end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
            end
         | 
| @@ -0,0 +1,25 @@ | |
| 1 | 
            +
            module MetaRequest
         | 
| 2 | 
            +
              module Middlewares
         | 
| 3 | 
            +
                class MetaRequestHandler
         | 
| 4 | 
            +
                  def initialize(app)
         | 
| 5 | 
            +
                    @app = app
         | 
| 6 | 
            +
                  end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                  def call(env)
         | 
| 9 | 
            +
                    request_id = env["PATH_INFO"][%r{/__meta_request/(.+)\.json$}, 1]
         | 
| 10 | 
            +
                    if request_id
         | 
| 11 | 
            +
                      events_json(request_id)
         | 
| 12 | 
            +
                    else
         | 
| 13 | 
            +
                      @app.call(env)
         | 
| 14 | 
            +
                    end
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  private
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                  def events_json(request_id)
         | 
| 20 | 
            +
                    events_json = Storage.new(request_id).read
         | 
| 21 | 
            +
                    [200, { "Content-Type" => "text/plain; charset=utf-8" }, [events_json]]
         | 
| 22 | 
            +
                  end
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
              end
         | 
| 25 | 
            +
            end
         | 
| @@ -0,0 +1,42 @@ | |
| 1 | 
            +
            require 'securerandom'
         | 
| 2 | 
            +
            require 'active_support/core_ext/string/access'
         | 
| 3 | 
            +
            require 'active_support/core_ext/object/blank'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            # Backported from Rails 3.2 (ActionDispatch::RequestId)
         | 
| 6 | 
            +
            module MetaRequest
         | 
| 7 | 
            +
              module Middlewares
         | 
| 8 | 
            +
                # Makes a unique request id available to the action_dispatch.request_id env variable (which is then accessible through
         | 
| 9 | 
            +
                # ActionDispatch::Request#uuid) and sends the same id to the client via the X-Request-Id header.
         | 
| 10 | 
            +
                #
         | 
| 11 | 
            +
                # The unique request id is either based off the X-Request-Id header in the request, which would typically be generated
         | 
| 12 | 
            +
                # by a firewall, load balancer, or the web server, or, if this header is not available, a random uuid. If the
         | 
| 13 | 
            +
                # header is accepted from the outside world, we sanitize it to a max of 255 chars and alphanumeric and dashes only.
         | 
| 14 | 
            +
                #
         | 
| 15 | 
            +
                # The unique request id can be used to trace a request end-to-end and would typically end up being part of log files
         | 
| 16 | 
            +
                # from multiple pieces of the stack.
         | 
| 17 | 
            +
                class RequestId
         | 
| 18 | 
            +
                  def initialize(app)
         | 
| 19 | 
            +
                    @app = app
         | 
| 20 | 
            +
                  end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  def call(env)
         | 
| 23 | 
            +
                    env["action_dispatch.request_id"] = external_request_id(env) || internal_request_id
         | 
| 24 | 
            +
                    status, headers, body = @app.call(env)
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                    headers["X-Request-Id"] = env["action_dispatch.request_id"]
         | 
| 27 | 
            +
                    [ status, headers, body ]
         | 
| 28 | 
            +
                  end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                  private
         | 
| 31 | 
            +
                    def external_request_id(env)
         | 
| 32 | 
            +
                      if request_id = env["HTTP_X_REQUEST_ID"].presence
         | 
| 33 | 
            +
                        request_id.gsub(/[^\w\-]/, "").first(255)
         | 
| 34 | 
            +
                      end
         | 
| 35 | 
            +
                    end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                    def internal_request_id
         | 
| 38 | 
            +
                      SecureRandom.hex(16)
         | 
| 39 | 
            +
                    end
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
              end
         | 
| 42 | 
            +
            end
         | 
| @@ -0,0 +1,8 @@ | |
| 1 | 
            +
            module MetaRequest
         | 
| 2 | 
            +
              module Middlewares
         | 
| 3 | 
            +
                autoload :Headers,            "meta_request/middlewares/headers"
         | 
| 4 | 
            +
                autoload :AppRequestHandler,  "meta_request/middlewares/app_request_handler"
         | 
| 5 | 
            +
                autoload :MetaRequestHandler, "meta_request/middlewares/meta_request_handler"
         | 
| 6 | 
            +
                autoload :RequestId,          "meta_request/middlewares/request_id"
         | 
| 7 | 
            +
              end
         | 
| 8 | 
            +
            end
         | 
| @@ -0,0 +1,24 @@ | |
| 1 | 
            +
            require 'rails/railtie'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module MetaRequest
         | 
| 4 | 
            +
              class Railtie < ::Rails::Railtie
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                initializer 'meta_request.inject_middlewares' do |app|
         | 
| 7 | 
            +
                  app.middleware.use Middlewares::RequestId unless defined?(ActionDispatch::RequestId)
         | 
| 8 | 
            +
                  app.middleware.use Middlewares::MetaRequestHandler
         | 
| 9 | 
            +
                  app.middleware.use Middlewares::Headers, app.config
         | 
| 10 | 
            +
                  app.middleware.use Middlewares::AppRequestHandler
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                initializer 'meta_request.log_interceptor' do
         | 
| 14 | 
            +
                  Rails.logger.extend(LogInterceptor) if Rails.logger
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                initializer 'meta_request.subscribe_to_notifications' do
         | 
| 18 | 
            +
                  AppNotifications.subscribe
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
            end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
             | 
| @@ -0,0 +1,43 @@ | |
| 1 | 
            +
            module MetaRequest
         | 
| 2 | 
            +
              class Storage
         | 
| 3 | 
            +
                attr_reader :key
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                def initialize(key)
         | 
| 6 | 
            +
                  @key = key
         | 
| 7 | 
            +
                end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                def write(value)
         | 
| 10 | 
            +
                  FileUtils.mkdir_p dir_path
         | 
| 11 | 
            +
                  File.open(json_file, 'wb') { |file| file.write(value) }
         | 
| 12 | 
            +
                  maintain_file_pool(10)
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                def read
         | 
| 16 | 
            +
                  File.read(json_file)
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                private
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                def maintain_file_pool(size)
         | 
| 22 | 
            +
                  files = Dir["#{dir_path}/*.json"]
         | 
| 23 | 
            +
                  files = files.sort_by { |f| -file_ctime(f) }
         | 
| 24 | 
            +
                  (files[size..-1] || []).each do |file|
         | 
| 25 | 
            +
                    FileUtils.rm_f(file)
         | 
| 26 | 
            +
                  end
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                def file_ctime(file)
         | 
| 30 | 
            +
                  File.stat(file).ctime.to_i 
         | 
| 31 | 
            +
                rescue Errno::ENOENT
         | 
| 32 | 
            +
                  0
         | 
| 33 | 
            +
                end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                def json_file
         | 
| 36 | 
            +
                  File.join(dir_path, "#{key}.json")
         | 
| 37 | 
            +
                end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                def dir_path
         | 
| 40 | 
            +
                  File.join(Rails.root, 'tmp', 'data', 'meta_request')
         | 
| 41 | 
            +
                end
         | 
| 42 | 
            +
              end
         | 
| 43 | 
            +
            end
         | 
    
        data/lib/meta_request.rb
    ADDED
    
    | @@ -0,0 +1,15 @@ | |
| 1 | 
            +
            module MetaRequest
         | 
| 2 | 
            +
              autoload :VERSION,          "meta_request/version"
         | 
| 3 | 
            +
              autoload :Event,            "meta_request/event"
         | 
| 4 | 
            +
              autoload :AppRequest,       "meta_request/app_request"
         | 
| 5 | 
            +
              autoload :Storage,          "meta_request/storage"
         | 
| 6 | 
            +
              autoload :Middlewares,      "meta_request/middlewares"
         | 
| 7 | 
            +
              autoload :LogInterceptor,   "meta_request/log_interceptor"
         | 
| 8 | 
            +
              autoload :AppNotifications, "meta_request/app_notifications"
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              def self.logger
         | 
| 11 | 
            +
                @@logger ||= Logger.new(File.join(Rails.root, 'log', 'meta_request.log'))
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
            end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            require "meta_request/railtie"
         | 
| @@ -0,0 +1,23 @@ | |
| 1 | 
            +
            # -*- encoding: utf-8 -*-
         | 
| 2 | 
            +
            lib = File.expand_path('../lib', __FILE__)
         | 
| 3 | 
            +
            $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
         | 
| 4 | 
            +
            require 'meta_request/version'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            Gem::Specification.new do |gem|
         | 
| 7 | 
            +
              gem.name          = "meta_request"
         | 
| 8 | 
            +
              gem.version       = MetaRequest::VERSION
         | 
| 9 | 
            +
              gem.authors       = ["Dejan Simic"]
         | 
| 10 | 
            +
              gem.email         = ["desimic@gmail.com"]
         | 
| 11 | 
            +
              gem.description   = %q{Request your request}
         | 
| 12 | 
            +
              gem.summary       = %q{Supporting gem for Rails Panel (Google Chrome extension for Rails development)}
         | 
| 13 | 
            +
              gem.homepage      = "https://github.com/dejan/rails_panel/tree/master/meta_request"
         | 
| 14 | 
            +
              
         | 
| 15 | 
            +
              gem.add_dependency('railties')
         | 
| 16 | 
            +
              gem.add_dependency('rack-contrib')
         | 
| 17 | 
            +
              gem.add_dependency('callsite')
         | 
| 18 | 
            +
             | 
| 19 | 
            +
              gem.files         = `git ls-files`.split($/)
         | 
| 20 | 
            +
              gem.executables   = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
         | 
| 21 | 
            +
              gem.test_files    = gem.files.grep(%r{^(test|spec|features)/})
         | 
| 22 | 
            +
              gem.require_paths = ["lib"]
         | 
| 23 | 
            +
            end
         | 
| @@ -0,0 +1,33 @@ | |
| 1 | 
            +
            require 'test_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe MetaRequest::AppNotifications do
         | 
| 4 | 
            +
              describe 'process_action.action_controller' do
         | 
| 5 | 
            +
                before do
         | 
| 6 | 
            +
                  @app_request = MetaRequest::AppRequest.new(17)
         | 
| 7 | 
            +
                  @app_request.current!
         | 
| 8 | 
            +
                  MetaRequest::AppNotifications.subscribe
         | 
| 9 | 
            +
                end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                describe 'status' do
         | 
| 12 | 
            +
                  it 'sets it to 500 if payload has exception key present' do
         | 
| 13 | 
            +
                    ActiveSupport::Notifications.instrument 'process_action.action_controller', {:exception => '...'}
         | 
| 14 | 
            +
                    assert_equal '500', @app_request.events.last.payload[:status]
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                describe 'format' do
         | 
| 19 | 
            +
                  it 'sets it' do
         | 
| 20 | 
            +
                    ActiveSupport::Notifications.instrument 'process_action.action_controller', {:format => 'html'}
         | 
| 21 | 
            +
                    assert_equal 'html', @app_request.events.last.payload[:format]
         | 
| 22 | 
            +
                  end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                  # Rails 3.0.x support
         | 
| 25 | 
            +
                  it 'sets it to first of formats if not set' do
         | 
| 26 | 
            +
                    ActiveSupport::Notifications.instrument 'process_action.action_controller', {:formats => ['js']}
         | 
| 27 | 
            +
                    assert_equal 'js', @app_request.events.last.payload[:format]
         | 
| 28 | 
            +
                  end
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
              end
         | 
| 31 | 
            +
            end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
             | 
| @@ -0,0 +1,34 @@ | |
| 1 | 
            +
            require 'test_helper'
         | 
| 2 | 
            +
            require 'tempfile'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            describe MetaRequest::Event do
         | 
| 5 | 
            +
              describe 'ignore_closed_tempfile_params' do
         | 
| 6 | 
            +
                it 'sets closed tempfiles in params to strings on create' do
         | 
| 7 | 
            +
                  tempfile = Tempfile.new('foo')
         | 
| 8 | 
            +
                  payload = {:params => {"user" => {"upload" => OpenStruct.new(:tempfile => tempfile)} } }.with_indifferent_access
         | 
| 9 | 
            +
                  event_1 = MetaRequest::Event.new('process_action.action_controller', 10, 11, 1705, payload)
         | 
| 10 | 
            +
                  assert_same tempfile, event_1.payload[:params][:user][:upload].tempfile
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  payload[:params][:user][:upload].tempfile.close
         | 
| 13 | 
            +
                  event_2 = MetaRequest::Event.new('process_action.action_controller', 10, 11, 1705, payload)
         | 
| 14 | 
            +
                  assert_equal 'Not JSON Encodable', event_2.payload[:params][:user][:upload]
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
              describe 'filter closed io objects in payload since they error on to_json' do
         | 
| 19 | 
            +
                before do
         | 
| 20 | 
            +
                  io = Tempfile.new('foo')
         | 
| 21 | 
            +
                  io.close
         | 
| 22 | 
            +
                  @event = MetaRequest::Event.new('sql.active_record', 10, 11, 1705, {:sql => 'select now();', :binds => io})
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                it 'should be filtered out' do
         | 
| 26 | 
            +
                  assert_equal({'sql' => 'select now();', 'binds' => 'Not JSON Encodable'}, @event.payload)
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                it 'should work to_json' do
         | 
| 30 | 
            +
                  @event.payload.to_json
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
              end
         | 
| 33 | 
            +
            end
         | 
| 34 | 
            +
             | 
| @@ -0,0 +1,22 @@ | |
| 1 | 
            +
            require 'test_helper'
         | 
| 2 | 
            +
            require 'logger'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            describe MetaRequest::LogInterceptor do
         | 
| 5 | 
            +
              before do
         | 
| 6 | 
            +
                @app_request = MetaRequest::AppRequest.new(17)
         | 
| 7 | 
            +
                @app_request.current!
         | 
| 8 | 
            +
                @app_request.events << 'mock'
         | 
| 9 | 
            +
                @logger = Logger.new("/dev/null")
         | 
| 10 | 
            +
                @logger.extend(MetaRequest::LogInterceptor)
         | 
| 11 | 
            +
              end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
              it 'adds app request events on log calls' do
         | 
| 14 | 
            +
                @logger.info('Ohai!')
         | 
| 15 | 
            +
                assert_equal 2, @app_request.events.size
         | 
| 16 | 
            +
                last_event = @app_request.events.last
         | 
| 17 | 
            +
                assert_equal 'Ohai!', last_event.payload[:message]
         | 
| 18 | 
            +
                assert_equal 14, last_event.payload[:line]
         | 
| 19 | 
            +
                assert_match /test\/meta_request\/log_interceptor_test.rb$/, last_event.payload[:filename]
         | 
| 20 | 
            +
                assert_equal :info, last_event.payload[:level]
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
            end
         | 
| @@ -0,0 +1,38 @@ | |
| 1 | 
            +
            require 'test_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe MetaRequest::Middlewares::MetaRequestHandler do
         | 
| 4 | 
            +
              before do
         | 
| 5 | 
            +
                MetaRequest::Storage.new('1234').write('abcdef')
         | 
| 6 | 
            +
                @app = MiniTest::Mock.new
         | 
| 7 | 
            +
                @middleware = MetaRequest::Middlewares::MetaRequestHandler.new(@app)
         | 
| 8 | 
            +
              end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              describe 'app request call' do
         | 
| 11 | 
            +
                it 'pushes request through the rest of the stack' do
         | 
| 12 | 
            +
                  env = {'PATH_INFO' => 'posts/1'}
         | 
| 13 | 
            +
                  @app.expect(:call, ':)', [env])
         | 
| 14 | 
            +
                  @middleware.call(env)
         | 
| 15 | 
            +
                  assert @app.verify
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
              describe 'meta request call' do
         | 
| 20 | 
            +
                it 'responds with json file' do
         | 
| 21 | 
            +
                  env = {'PATH_INFO' => '/__meta_request/1234.json'}
         | 
| 22 | 
            +
                  response = @middleware.call(env)
         | 
| 23 | 
            +
                  assert_equal [200, { "Content-Type" => "text/plain; charset=utf-8" }, ['abcdef']], response 
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              describe 'meta request call within a subfolder' do
         | 
| 28 | 
            +
                it 'responds with json file' do
         | 
| 29 | 
            +
                  env = {'PATH_INFO' => '/any/subfolder/__meta_request/1234.json'}
         | 
| 30 | 
            +
                  response = @middleware.call(env)
         | 
| 31 | 
            +
                  assert_equal [200, { "Content-Type" => "text/plain; charset=utf-8" }, ['abcdef']], response
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
              end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
              after do
         | 
| 36 | 
            +
                FileUtils.rm_rf "#{Dir.pwd}/tmp"
         | 
| 37 | 
            +
              end
         | 
| 38 | 
            +
            end
         | 
| @@ -0,0 +1,26 @@ | |
| 1 | 
            +
            require 'test_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe MetaRequest::Storage do
         | 
| 4 | 
            +
              before do
         | 
| 5 | 
            +
                @dir_path = MetaRequest::Storage.new(nil).send(:dir_path)
         | 
| 6 | 
            +
                FileUtils.mkdir_p @dir_path
         | 
| 7 | 
            +
              end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              describe 'write' do
         | 
| 10 | 
            +
                it 'writes to file' do
         | 
| 11 | 
            +
                  MetaRequest::Storage.new('1234').write('abcdef')
         | 
| 12 | 
            +
                  assert_equal 'abcdef', File.read("#{@dir_path}/1234.json")
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
              describe 'read' do
         | 
| 17 | 
            +
                it 'reads from file' do
         | 
| 18 | 
            +
                  File.open("#{@dir_path}/foo.json", "w") { |file| file.write('bar') }
         | 
| 19 | 
            +
                  assert_equal 'bar', MetaRequest::Storage.new('foo').read
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              after do
         | 
| 24 | 
            +
                FileUtils.rm_rf "#{Rails.root}/tmp"
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
            end
         | 
    
        data/test/test_helper.rb
    ADDED
    
    
    
        metadata
    ADDED
    
    | @@ -0,0 +1,124 @@ | |
| 1 | 
            +
            --- !ruby/object:Gem::Specification
         | 
| 2 | 
            +
            name: meta_request
         | 
| 3 | 
            +
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            +
              version: 0.2.9
         | 
| 5 | 
            +
              prerelease: 
         | 
| 6 | 
            +
            platform: ruby
         | 
| 7 | 
            +
            authors:
         | 
| 8 | 
            +
            - Dejan Simic
         | 
| 9 | 
            +
            autorequire: 
         | 
| 10 | 
            +
            bindir: bin
         | 
| 11 | 
            +
            cert_chain: []
         | 
| 12 | 
            +
            date: 2014-04-07 00:00:00.000000000 Z
         | 
| 13 | 
            +
            dependencies:
         | 
| 14 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 15 | 
            +
              name: railties
         | 
| 16 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 17 | 
            +
                none: false
         | 
| 18 | 
            +
                requirements:
         | 
| 19 | 
            +
                - - ! '>='
         | 
| 20 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 21 | 
            +
                    version: '0'
         | 
| 22 | 
            +
              type: :runtime
         | 
| 23 | 
            +
              prerelease: false
         | 
| 24 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 25 | 
            +
                none: false
         | 
| 26 | 
            +
                requirements:
         | 
| 27 | 
            +
                - - ! '>='
         | 
| 28 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 29 | 
            +
                    version: '0'
         | 
| 30 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 31 | 
            +
              name: rack-contrib
         | 
| 32 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 33 | 
            +
                none: false
         | 
| 34 | 
            +
                requirements:
         | 
| 35 | 
            +
                - - ! '>='
         | 
| 36 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 37 | 
            +
                    version: '0'
         | 
| 38 | 
            +
              type: :runtime
         | 
| 39 | 
            +
              prerelease: false
         | 
| 40 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 41 | 
            +
                none: false
         | 
| 42 | 
            +
                requirements:
         | 
| 43 | 
            +
                - - ! '>='
         | 
| 44 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 45 | 
            +
                    version: '0'
         | 
| 46 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 47 | 
            +
              name: callsite
         | 
| 48 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 49 | 
            +
                none: false
         | 
| 50 | 
            +
                requirements:
         | 
| 51 | 
            +
                - - ! '>='
         | 
| 52 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 53 | 
            +
                    version: '0'
         | 
| 54 | 
            +
              type: :runtime
         | 
| 55 | 
            +
              prerelease: false
         | 
| 56 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 57 | 
            +
                none: false
         | 
| 58 | 
            +
                requirements:
         | 
| 59 | 
            +
                - - ! '>='
         | 
| 60 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 61 | 
            +
                    version: '0'
         | 
| 62 | 
            +
            description: Request your request
         | 
| 63 | 
            +
            email:
         | 
| 64 | 
            +
            - desimic@gmail.com
         | 
| 65 | 
            +
            executables: []
         | 
| 66 | 
            +
            extensions: []
         | 
| 67 | 
            +
            extra_rdoc_files: []
         | 
| 68 | 
            +
            files:
         | 
| 69 | 
            +
            - .gitignore
         | 
| 70 | 
            +
            - Gemfile
         | 
| 71 | 
            +
            - LICENSE.txt
         | 
| 72 | 
            +
            - README.md
         | 
| 73 | 
            +
            - Rakefile
         | 
| 74 | 
            +
            - lib/meta_request.rb
         | 
| 75 | 
            +
            - lib/meta_request/app_notifications.rb
         | 
| 76 | 
            +
            - lib/meta_request/app_request.rb
         | 
| 77 | 
            +
            - lib/meta_request/event.rb
         | 
| 78 | 
            +
            - lib/meta_request/log_interceptor.rb
         | 
| 79 | 
            +
            - lib/meta_request/middlewares.rb
         | 
| 80 | 
            +
            - lib/meta_request/middlewares/app_request_handler.rb
         | 
| 81 | 
            +
            - lib/meta_request/middlewares/headers.rb
         | 
| 82 | 
            +
            - lib/meta_request/middlewares/meta_request_handler.rb
         | 
| 83 | 
            +
            - lib/meta_request/middlewares/request_id.rb
         | 
| 84 | 
            +
            - lib/meta_request/railtie.rb
         | 
| 85 | 
            +
            - lib/meta_request/storage.rb
         | 
| 86 | 
            +
            - lib/meta_request/version.rb
         | 
| 87 | 
            +
            - meta_request.gemspec
         | 
| 88 | 
            +
            - test/meta_request/app_notifications_test.rb
         | 
| 89 | 
            +
            - test/meta_request/event_test.rb
         | 
| 90 | 
            +
            - test/meta_request/log_interceptor_test.rb
         | 
| 91 | 
            +
            - test/meta_request/middlewares/meta_request_handler_test.rb
         | 
| 92 | 
            +
            - test/meta_request/storage_test.rb
         | 
| 93 | 
            +
            - test/test_helper.rb
         | 
| 94 | 
            +
            homepage: https://github.com/dejan/rails_panel/tree/master/meta_request
         | 
| 95 | 
            +
            licenses: []
         | 
| 96 | 
            +
            post_install_message: 
         | 
| 97 | 
            +
            rdoc_options: []
         | 
| 98 | 
            +
            require_paths:
         | 
| 99 | 
            +
            - lib
         | 
| 100 | 
            +
            required_ruby_version: !ruby/object:Gem::Requirement
         | 
| 101 | 
            +
              none: false
         | 
| 102 | 
            +
              requirements:
         | 
| 103 | 
            +
              - - ! '>='
         | 
| 104 | 
            +
                - !ruby/object:Gem::Version
         | 
| 105 | 
            +
                  version: '0'
         | 
| 106 | 
            +
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 107 | 
            +
              none: false
         | 
| 108 | 
            +
              requirements:
         | 
| 109 | 
            +
              - - ! '>='
         | 
| 110 | 
            +
                - !ruby/object:Gem::Version
         | 
| 111 | 
            +
                  version: '0'
         | 
| 112 | 
            +
            requirements: []
         | 
| 113 | 
            +
            rubyforge_project: 
         | 
| 114 | 
            +
            rubygems_version: 1.8.23
         | 
| 115 | 
            +
            signing_key: 
         | 
| 116 | 
            +
            specification_version: 3
         | 
| 117 | 
            +
            summary: Supporting gem for Rails Panel (Google Chrome extension for Rails development)
         | 
| 118 | 
            +
            test_files:
         | 
| 119 | 
            +
            - test/meta_request/app_notifications_test.rb
         | 
| 120 | 
            +
            - test/meta_request/event_test.rb
         | 
| 121 | 
            +
            - test/meta_request/log_interceptor_test.rb
         | 
| 122 | 
            +
            - test/meta_request/middlewares/meta_request_handler_test.rb
         | 
| 123 | 
            +
            - test/meta_request/storage_test.rb
         | 
| 124 | 
            +
            - test/test_helper.rb
         |