Class: Contrast::Framework::Sinatra::Support

Inherits:
Object
  • Object
show all
Extended by:
BaseSupport
Defined in:
lib/contrast/framework/sinatra/support.rb

Overview

Used when Sinatra is present to define framework specific behavior

Class Method Summary collapse

Methods included from BaseSupport

after_load_patches, application_name, before_load_patches!, collect_routes, current_route_coverage, detection_class, retrieve_request, server_type, streaming?, version

Class Method Details

.after_load_patchesObject

(See BaseSupport#after_load_patches)



109
110
111
112
113
114
115
116
117
118
119
# File 'lib/contrast/framework/sinatra/support.rb', line 109

def after_load_patches
  return unless defined?(::Sinatra)
  return unless Gem::Version.new(version) >= Gem::Version.new('3.0.0')

  Set.new([
            Contrast::Agent::Patching::Policy::AfterLoadPatch.new(
                'Rack::Protection::EncryptedCookie',
                'contrast/framework/sinatra/patch/encrypted_session_cookie',
                instrumenting_module: 'Contrast::Framework::Sinatra::Patch::EncryptedSessionCookie')
          ])
end

.application_nameObject



22
23
24
# File 'lib/contrast/framework/sinatra/support.rb', line 22

def application_name
  app_class&.cs__name
end

.application_rootObject



26
27
28
# File 'lib/contrast/framework/sinatra/support.rb', line 26

def application_root
  app_instance&.root
end

.collect_routesArray<Contrast::Agent::Reporting::DiscoveredRoute>

Find all classes that subclass ::Sinatra::Base. Gather their routes.

Returns:



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/contrast/framework/sinatra/support.rb', line 51

def collect_routes
  return Contrast::Utils::ObjectShare::EMPTY_ARRAY unless defined?(::Sinatra) && defined?(::Sinatra::Base)

  routes = []
  sinatra_controllers.each do |controller|
    controller.routes.each_pair do |method, route_triplets|
      # Sinatra stores its routes as a triplet: [Mustermann::Sinatra, [], Proc]
      route_triplets.map(&:first).each do |route_pattern|
        routes << Contrast::Agent::Reporting::DiscoveredRoute.from_sinatra_route(controller, method,
                                                                                 route_pattern)
      end
    end
  end
  routes
end

.current_route_coverage(request, _controller = ::Sinatra::Base, full_route = nil) ⇒ Contrast::Agent::Reporting::RouteCoverage?

Returns the route coverage object or nil if no route.

Parameters:

  • a contrast tracked request.

  • (defaults to: ::Sinatra::Base)

    optionally use this controller instead of global ::Sinatra::Base.

Returns:

  • the route coverage object or nil if no route



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/contrast/framework/sinatra/support.rb', line 72

def current_route_coverage request, _controller = ::Sinatra::Base, full_route = nil
  method = request.env[::Rack::REQUEST_METHOD] # GET, PUT, POST, etc...
  route = _cleaned_route(request)
  # Find route match--checking superclasses if necessary.
  sinatra_controllers.each do |potential_controller|
    next unless sinatra_controller?(potential_controller)

    next if potential_controller.nil? || potential_controller.cs__class == NilClass

    route_patterns = potential_controller.routes.fetch(method) { [] }.
        map(&:first)
    route_pattern = route_patterns.find do |matcher|
      matcher.params(route) # ::Mustermann::Sinatra match.
    end
    next unless route_pattern

    full_route ||= request.env[::Rack::PATH_INFO]
    new_route_coverage = Contrast::Agent::Reporting::RouteCoverage.new
    new_route_coverage.attach_rack_based_data(potential_controller, method, route_pattern, full_route)
    return new_route_coverage
  end
  nil
end

.detection_classObject



14
15
16
# File 'lib/contrast/framework/sinatra/support.rb', line 14

def detection_class
  'Sinatra'
end

.retrieve_request(env) ⇒ Object



104
105
106
# File 'lib/contrast/framework/sinatra/support.rb', line 104

def retrieve_request env
  ::Sinatra::Request.new(env)
end

.server_typeObject



30
31
32
# File 'lib/contrast/framework/sinatra/support.rb', line 30

def server_type
  'sinatra'
end

.sinatra_controller?(app) ⇒ Boolean

Given an object, determine if it is a Sinatra controller with routes.

Parameters:

  • suspected Sinatra app.

Returns:



38
39
40
41
42
43
44
45
46
# File 'lib/contrast/framework/sinatra/support.rb', line 38

def sinatra_controller? app
  # Sinatra is loaded?
  return false unless defined?(::Sinatra) && defined?(::Sinatra::Base)
  # App is a subclass of or actually is ::Sinatra::Base.
  return false unless (app.cs__respond_to?(:<) && app < ::Sinatra::Base) || app == ::Sinatra::Base

  # App has routes.
  !app.routes.empty?
end

.sinatra_controllersArray<Class<::Sinatra::Base>>

Search object space for sinatra controllers--any class that subclasses ::Sinatra::Base.

Returns:

  • sinatra controlelrs



99
100
101
102
# File 'lib/contrast/framework/sinatra/support.rb', line 99

def sinatra_controllers
  @_sinatra_controllers ||=
    [::Sinatra::Base] + ObjectSpace.each_object(Class).select { |clazz| sinatra_controller?(clazz) }
end

.versionObject



18
19
20
# File 'lib/contrast/framework/sinatra/support.rb', line 18

def version
  ::Sinatra::VERSION
end