# typed: ignore # Copyright (c) 2015 Sqreen. All Rights Reserved. # Please refer to our terms for more information: https://www.sqreen.com/terms.html require 'sqreen/shrink_wrap' require 'sqreen/middleware' require 'sqreen/error_handling_middleware' require 'sqreen/sinatra_middleware' module Sqreen module Dependency module Sinatra module_function def required? Sqreen::Dependency.const_exist?('Sinatra::Base') end def insert_sqreen_middlewares(builder, *args, &block) Sqreen.log.debug { 'Inserting Sqreen middlewares for Sinatra' } insert_middleware(builder, Sqreen::ErrorHandlingMiddleware, args, block) do |p, u| if middlewares(builder).include?(::Sinatra::ShowExceptions) Sqreen.log.warn('Sinatra :show_exceptions detected: Sinatra exception handling may prevent the Sqreen error page to display on attacks.') end if (i = middlewares(builder).index(::Rack::Head)) u.insert(i, p) elsif (i = middlewares(builder).index(::Rack::MethodOverride)) u.insert(i + 1, p) elsif (i = middlewares(builder).index(::Sinatra::ExtendedRack)) u.insert(i + 1, p) else u.insert(0, p) end end insert_middleware(builder, Sqreen::ShrinkWrap, args, block) do |p, u| if (i = middlewares(builder).index(::Sinatra::ExtendedRack)) u.insert(i, p) else u.insert(0, p) end end insert_middleware(builder, Sqreen::Middleware, args, block) do |p, u| if (i = middlewares(builder).index(::Sinatra::ExtendedRack)) u.insert(i, p) else u.insert(1, p) end end insert_middleware(builder, Sqreen::SinatraMiddleware, args, block) do |p, u| if ::Sqreen::Dependency.const_exist?('Rack::PostBodyContentTypeParser') && (i = middlewares(builder).index(::Rack::PostBodyContentTypeParser)) u.insert(i + 1, p) elsif (i = middlewares(builder).index(::Rack::Protection)) u.insert(i + 1, p) else u.append(p) end end insert_datadog_middleware(builder, *args, &block) end def insert_datadog_middleware(builder, *args, &block) return unless defined?(Datadog) && Datadog.respond_to?(:configuration) && Datadog.configuration.instrumented_integrations.key?(:sinatra) Datadog.configure do |c| sinatra_config = Datadog.configuration[:sinatra] c.use( :rack, service_name: sinatra_config[:service_name], distributed_tracing: sinatra_config[:distributed_tracing], ) unless Datadog.configuration.instrumented_integrations.key?(:rack) end insert_middleware(builder, Datadog::Contrib::Rack::TraceMiddleware, args, block) do |p, u| u.insert(0, p) end end def wrap_middleware(middleware, *args, &block) proc { |app| middleware.new(app, *args, &block) } end def insert_middleware(builder, middleware, args, block) use = builder.instance_variable_get('@use') wrapped = wrap_middleware(middleware, *args, &block) catch(:skip) do throw(:skip) if middlewares(builder).include?(middleware) yield(wrapped, use) end end def inspect_middlewares(builder) Sqreen.log.debug do "Middlewares: " << middlewares(builder).map(&:inspect).inspect end end def middlewares(builder) builder.instance_variable_get(:@use).map do |p| unless p.respond_to?(:binding) && p.binding.local_variable_defined?(:middleware) next :unknown end p.binding.local_variable_get(:middleware) end end end end end