rack-webprofiler 0.1.0.pre.alpha1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +7 -0
  2. data/.editorconfig +27 -0
  3. data/.gitignore +11 -0
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +34 -0
  6. data/.rubocop_todo.yml +0 -0
  7. data/.travis.yml +23 -0
  8. data/CHANGELOG.md +39 -0
  9. data/CODE_OF_CONDUCT.md +74 -0
  10. data/Gemfile +15 -0
  11. data/LICENSE +21 -0
  12. data/README.md +94 -0
  13. data/Rakefile +17 -0
  14. data/bin/ci-prepare +16 -0
  15. data/bin/console +10 -0
  16. data/bin/setup +8 -0
  17. data/examples/README.md +56 -0
  18. data/examples/rack/config.ru +52 -0
  19. data/examples/sinatra/app.rb +37 -0
  20. data/examples/sinatra/config.ru +3 -0
  21. data/lib/rack/templates/404.erb +1 -0
  22. data/lib/rack/templates/assets/rwpt.css +9 -0
  23. data/lib/rack/templates/assets/rwpt.js +0 -0
  24. data/lib/rack/templates/async.erb +120 -0
  25. data/lib/rack/templates/panel/index.erb +29 -0
  26. data/lib/rack/templates/panel/layout.erb +17 -0
  27. data/lib/rack/templates/panel/show.erb +19 -0
  28. data/lib/rack/templates/profiler.erb +70 -0
  29. data/lib/rack/web_profiler/auto_configure/rails.rb +12 -0
  30. data/lib/rack/web_profiler/collector/debug_collector.rb +31 -0
  31. data/lib/rack/web_profiler/collector/erb_collector.rb +0 -0
  32. data/lib/rack/web_profiler/collector/performance_collector.rb +1 -0
  33. data/lib/rack/web_profiler/collector/rack/rack_collector.rb +23 -0
  34. data/lib/rack/web_profiler/collector/rack/request_collector.rb +33 -0
  35. data/lib/rack/web_profiler/collector/rails/active_record_collector.rb +25 -0
  36. data/lib/rack/web_profiler/collector/rails/logger_collector.rb +22 -0
  37. data/lib/rack/web_profiler/collector/rails/rails_collector.rb +25 -0
  38. data/lib/rack/web_profiler/collector/rails/request_collector.rb +50 -0
  39. data/lib/rack/web_profiler/collector/ruby_collector.rb +46 -0
  40. data/lib/rack/web_profiler/collector/sinatra/request_collector.rb +38 -0
  41. data/lib/rack/web_profiler/collector/sinatra/sinatra_collector.rb +25 -0
  42. data/lib/rack/web_profiler/collector/time_collector.rb +23 -0
  43. data/lib/rack/web_profiler/collector.rb +142 -0
  44. data/lib/rack/web_profiler/collectors.rb +88 -0
  45. data/lib/rack/web_profiler/config.rb +61 -0
  46. data/lib/rack/web_profiler/controller.rb +125 -0
  47. data/lib/rack/web_profiler/engine.rb +109 -0
  48. data/lib/rack/web_profiler/erb.rb +9 -0
  49. data/lib/rack/web_profiler/model/collection_record.rb +45 -0
  50. data/lib/rack/web_profiler/model.rb +35 -0
  51. data/lib/rack/web_profiler/request.rb +14 -0
  52. data/lib/rack/web_profiler/router.rb +71 -0
  53. data/lib/rack/web_profiler/version.rb +5 -0
  54. data/lib/rack/web_profiler.rb +70 -0
  55. data/lib/rack/webprofiler.rb +1 -0
  56. data/rack-webprofiler.gemspec +38 -0
  57. metadata +198 -0
@@ -0,0 +1,142 @@
1
+ require "docile"
2
+
3
+ module Rack
4
+
5
+ # Collector
6
+ class WebProfiler::Collector
7
+ autoload :RubyCollector, "rack/web_profiler/collector/ruby_collector"
8
+ autoload :TimeCollector, "rack/web_profiler/collector/time_collector"
9
+
10
+ module Rack
11
+ autoload :RackCollector, "rack/web_profiler/collector/rack/rack_collector"
12
+ autoload :RequestCollector, "rack/web_profiler/collector/rack/request_collector"
13
+ end
14
+
15
+ module Rails
16
+ autoload :ActiveRecordCollector, "rack/web_profiler/collector/rails/active_record_collector"
17
+ autoload :LoggerCollector, "rack/web_profiler/collector/rails/logger_collector"
18
+ autoload :RailsCollector, "rack/web_profiler/collector/rails/rails_collector"
19
+ autoload :RequestCollector, "rack/web_profiler/collector/rails/request_collector"
20
+ end
21
+
22
+ module Sinatra
23
+ autoload :RequestCollector, "rack/web_profiler/collector/sinatra/request_collector"
24
+ autoload :SinatraCollector, "rack/web_profiler/collector/sinatra/sinatra_collector"
25
+ end
26
+
27
+ # DSL
28
+ module DSL
29
+ def self.included(base)
30
+ base.extend(ClassMethods)
31
+ base.class_eval do
32
+ @definition = Definition.new
33
+ @definition.position = 1
34
+ @definition.is_enabled = true
35
+ @definition.klass = self
36
+ end
37
+ end
38
+
39
+ module ClassMethods
40
+ attr_reader :definition
41
+
42
+ def icon(icon = nil); definition.icon = icon; end
43
+ def collector_name(name = nil); definition.name = name; end
44
+ def position(position = nil); definition.position = position.to_i; end
45
+ def collect(&block); definition.collect = block; end
46
+
47
+ def template(template = nil, type: :file)
48
+ template = get_data_contents(template) if type == :DATA
49
+ definition.template = template
50
+ end
51
+
52
+ def is_enabled?(is_enabled = true)
53
+ definition.is_enabled = Proc.new if block_given?
54
+ definition.is_enabled = is_enabled
55
+ end
56
+
57
+ private
58
+
59
+ def get_data_contents(path)
60
+ data = ""
61
+ ::File.open(path, "rb") do |f|
62
+ begin
63
+ line = f.gets
64
+ end until line.nil? || /^__END__$/ === line
65
+ data << line while line = f.gets
66
+ end
67
+ data
68
+ end
69
+ end
70
+ end
71
+
72
+ # Definition
73
+ #
74
+ # Collector definition.
75
+ class Definition
76
+ attr_accessor :icon, :name, :position, :collect, :template, :is_enabled, :klass
77
+ attr_reader :data_storage
78
+
79
+ # Collect the data who the Collector need.
80
+ #
81
+ # @param request [Rack::WebProfiler::Request]
82
+ # @param response [Rack::Response]
83
+ #
84
+ # @return [Rack::WebProfiler::Collector::DSL::DataStorage]
85
+ def collect!(request, response)
86
+ @data_storage = Docile.dsl_eval(DataStorage.new, request, response, &collect)
87
+ end
88
+
89
+ # Is the collector enabled.
90
+ #
91
+ # @return [Boolean]
92
+ def is_enabled?
93
+ return !!@is_enabled.call if @is_enabled.is_a?(Proc)
94
+ !!@is_enabled
95
+ end
96
+ end
97
+
98
+ # DataStorage
99
+ #
100
+ # Used to store datas who Collector needs.
101
+ #
102
+ # @todo do DataStorage compatible with Marshal
103
+ class DataStorage
104
+ attr_reader :datas
105
+
106
+ def initialize
107
+ @datas = Hash.new
108
+ @status = nil
109
+ end
110
+
111
+ # Store a value.
112
+ #
113
+ # @param k [String, Symbol]
114
+ # @param v
115
+ def store(k, v)
116
+ # @todo check data format (must be compatible with Marshal)
117
+ @datas[k.to_sym] = v
118
+ end
119
+
120
+ # Status.
121
+ #
122
+ # @param v [Symbol, nil]
123
+ #
124
+ # @return [Symbol, nil]
125
+ def status(v = nil)
126
+ # @todo check status?
127
+ @status = v.to_sym unless v.nil?
128
+ @status
129
+ end
130
+
131
+ # Transform DataStorage to an Hash
132
+ #
133
+ # @return [Hash<Symbol, Object>]
134
+ def to_h
135
+ {
136
+ datas: @datas,
137
+ status: @status
138
+ }
139
+ end
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,88 @@
1
+ module Rack
2
+
3
+ # Collectors.
4
+ #
5
+ # Container of Collector objects.
6
+ class WebProfiler::Collectors
7
+
8
+ # Initialize.
9
+ def initialize
10
+ @collectors = {}
11
+ @sorted_collectors = {}
12
+ end
13
+
14
+ # Get a collector definition by his name.
15
+ #
16
+ # @param name [String]
17
+ #
18
+ # @return [Rack::WebProfiler::Collector::DSL::Definition, nil]
19
+ def definition_by_name(name)
20
+ name = name.to_sym
21
+ @sorted_collectors[name] unless @sorted_collectors[name].nil?
22
+ end
23
+
24
+ # Returns all collectors definition.
25
+ #
26
+ # @return [Hash<Symbol, Rack::WebProfiler::Collector::DSL::Definition>]
27
+ def all
28
+ @sorted_collectors
29
+ end
30
+
31
+ # Add a collector.
32
+ #
33
+ # @param collector_class [Class]
34
+ #
35
+ # @raise [ArgumentError] if `collector_class' is not a Class or is not an instance of Rack::WebProfiler::Collector::DSL
36
+ # or a collector with this name is already registrered.
37
+ def add_collector(collector_class)
38
+ unless collector_class.is_a? Class
39
+ raise ArgumentError, "`collector_class' must be a class"
40
+ end
41
+
42
+ unless collector_class.included_modules.include?(Rack::WebProfiler::Collector::DSL)
43
+ raise ArgumentError, "#{collector_class.class.name} must be an instance of \"Rack::WebProfiler::Collector::DSL\""
44
+ end
45
+
46
+ definition = collector_class.definition
47
+
48
+ if definition_by_name(definition.name)
49
+ raise ArgumentError, "A collector with name \“#{definition.name}\" already exists"
50
+ end
51
+
52
+ return false unless definition.is_enabled?
53
+
54
+ @collectors[collector_class] = definition
55
+
56
+ sort_collectors!
57
+ end
58
+
59
+ # Remove a collector.
60
+ #
61
+ # @param collector_class [Class]
62
+ #
63
+ # @raise [ArgumentError] if `collector_class' is not a Class or if this collector is not registered.
64
+ def remove_collector(collector_class)
65
+ unless collector_class.is_a? Class
66
+ raise ArgumentError, "`collector_class' must be a class"
67
+ end
68
+
69
+ unless @collectors[collector_class]
70
+ raise ArgumentError, "No collector found with class \“#{collector_class}\""
71
+ end
72
+
73
+ @collectors.delete(collector_class)
74
+
75
+ sort_collectors!
76
+ end
77
+
78
+ private
79
+
80
+ # Sort collectors by definition name.
81
+ def sort_collectors!
82
+ @sorted_collectors = {}
83
+
84
+ tmp = @collectors.sort_by { |_klass, definition| definition.position }
85
+ tmp.each { |_k, v| @sorted_collectors[v.name.to_sym] = v }
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,61 @@
1
+ require "fileutils"
2
+
3
+ module Rack
4
+ # Config
5
+ class WebProfiler::Config
6
+ attr_accessor :collectors, :tmp_dir
7
+
8
+ DEFAULT_COLLECTORS = [
9
+ # Commons
10
+ Rack::WebProfiler::Collector::RubyCollector,
11
+ Rack::WebProfiler::Collector::TimeCollector,
12
+
13
+ # Rack
14
+ # Rack::WebProfiler::Collector::Rack::RackCollector,
15
+ Rack::WebProfiler::Collector::Rack::RequestCollector,
16
+
17
+ # Rails
18
+ # Rack::WebProfiler::Collector::Rails::ActiveRecordCollector,
19
+ # Rack::WebProfiler::Collector::Rails::LoggerCollector,
20
+ Rack::WebProfiler::Collector::Rails::RailsCollector,
21
+ Rack::WebProfiler::Collector::Rails::RequestCollector,
22
+
23
+ # Sinatra
24
+ Rack::WebProfiler::Collector::Sinatra::RequestCollector,
25
+ Rack::WebProfiler::Collector::Sinatra::SinatraCollector,
26
+ ].freeze
27
+ def initialize
28
+ @collectors = Rack::WebProfiler::Collectors.new
29
+
30
+ load_defaults!
31
+ end
32
+
33
+ # Setup the configuration
34
+ #
35
+ # @param [block] block
36
+ def build!
37
+ unless block_given?
38
+ # @todo raise an Exception if no block given
39
+ end
40
+ instance_eval(&Proc.new)
41
+ end
42
+
43
+ # protected
44
+
45
+ def tmp_dir
46
+ FileUtils.mkdir_p @tmp_dir
47
+ @tmp_dir
48
+ end
49
+
50
+ private
51
+
52
+ def load_defaults!
53
+ # Add default collectors
54
+ DEFAULT_COLLECTORS.each do |collector_class|
55
+ @collectors.add_collector(collector_class)
56
+ end
57
+
58
+ @tmp_dir = Dir.tmpdir
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,125 @@
1
+ require "erb"
2
+ require "json"
3
+
4
+ module Rack
5
+ # Controller
6
+ #
7
+ # Generate the views of the WebProfiler.
8
+ class WebProfiler::Controller
9
+ # Initialize
10
+ #
11
+ # @param request [Rack::WebProfiler::Request]
12
+ def initialize(request)
13
+ @request = request
14
+ @contents_for = {}
15
+ end
16
+
17
+ # List the webprofiler history.
18
+ def index
19
+ @collections = Rack::WebProfiler::Model::CollectionRecord.order(Sequel.desc(:created_at))
20
+ .limit(20)
21
+
22
+ erb "panel/index.erb", layout: "panel/layout.erb"
23
+ end
24
+
25
+ # Show the webprofiler panel.
26
+ def show(token)
27
+ @collection = Rack::WebProfiler::Model::CollectionRecord[token: token]
28
+ return error404 if @collection.nil?
29
+
30
+ @collectors = Rack::WebProfiler.config.collectors.all
31
+
32
+ # @todo return json if request.content_type ask json (same for xml?)
33
+ # @example json {} if @request.media_type.include? "json"
34
+
35
+ erb "panel/show.erb", layout: "panel/layout.erb"
36
+ end
37
+
38
+ # Print the webprofiler toolbar
39
+ def show_toolbar(token)
40
+ @collection = Rack::WebProfiler::Model::CollectionRecord[token: token]
41
+ return erb nil, status: 404 if @collection.nil?
42
+
43
+ @collectors = Rack::WebProfiler.config.collectors.all
44
+ # @todo process the callector views
45
+ # @collectors = Rack::WebProfiler::Collector.render_tabs(@record)
46
+
47
+ erb "profiler.erb"
48
+ end
49
+
50
+ # Clean the webprofiler.
51
+ def delete
52
+ Rack::WebProfiler::Model.clean
53
+
54
+ redirect WebProfiler::Router.url_for_profiler
55
+ end
56
+
57
+ private
58
+
59
+ def redirect(path)
60
+ Rack::Response.new([], 302, {
61
+ "Location" => "#{@request.base_url}#{path}",
62
+ })
63
+ end
64
+
65
+ # Render a HTML reponse from an ERB template.
66
+ #
67
+ # @param path [String] Path to the ERB template
68
+ #
69
+ # @return [Rack::Response]
70
+ def erb(path, layout: nil, status: 200)
71
+ content = ""
72
+
73
+ unless path.nil?
74
+ templates = [read_template(path)]
75
+ templates << read_template(layout) unless layout.nil?
76
+
77
+ content = templates.inject(nil) do |prev, temp|
78
+ _render_erb(temp) { prev }
79
+ end
80
+ end
81
+
82
+ Rack::Response.new(content, status, {
83
+ "Content-Type" => "text/html",
84
+ })
85
+ end
86
+
87
+ # Render a JSON response from an Array or a Hash.
88
+ #
89
+ # @param data [Array, Hash] Data
90
+ #
91
+ # @return [Rack::Response]
92
+ def json(data = {})
93
+ Rack::Response.new(data.to_json, 200, {
94
+ "Content-Type" => "application/json",
95
+ })
96
+ end
97
+
98
+ def error404
99
+ erb "404.erb", layout: "panel/layout.erb", status: 404
100
+ end
101
+
102
+ def _render_erb(template)
103
+ ERB.new(template).result(binding)
104
+ end
105
+
106
+ def partial(path)
107
+ return "" if path.nil?
108
+ ERB.new(read_template(path)).result(binding)
109
+ end
110
+
111
+ def render_collector(path, data)
112
+ @data = data
113
+ return "" if path.nil?
114
+ ERB.new(read_template(path)).result(binding)
115
+ end
116
+
117
+ def read_template(template)
118
+ unless template.empty?
119
+ path = ::File.expand_path("../../templates/#{template}", __FILE__)
120
+ return ::File.read(path) if ::File.exist?(path)
121
+ end
122
+ template
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,109 @@
1
+ module Rack
2
+ #
3
+ class WebProfiler::Engine
4
+ class << self
5
+ # Process
6
+ #
7
+ # @param request [Rack::WebProfiler::Request]
8
+ # @param body
9
+ # @param status
10
+ # @param headers
11
+ #
12
+ # @return [Rack::Response]
13
+ def process(request, body, status, headers)
14
+ response = Rack::Response.new(body, status, headers)
15
+ record = collect!(request, response)
16
+
17
+ return response if !headers[CONTENT_TYPE].nil? and !headers[CONTENT_TYPE].include? "text/html"
18
+
19
+ @token = record.token
20
+ @url = WebProfiler::Router.url_for_toolbar(record.token)
21
+
22
+ response = Rack::Response.new([], status, headers)
23
+
24
+ response.header["X-RackWebProfiler-Token"] = @token
25
+ response.header["X-RackWebProfiler-Url"] = @url
26
+
27
+ if defined? Rails and body.is_a? ActionDispatch::Response::RackBody
28
+ body = body.body
29
+ end
30
+
31
+ if body.is_a? Array
32
+ body.each { |fragment| response.write inject(fragment) }
33
+ elsif body.is_a? String
34
+ response.write inject(body)
35
+ end
36
+
37
+ response
38
+ end
39
+
40
+ private
41
+
42
+ # Collect
43
+ #
44
+ # @param request
45
+ # @param response
46
+ def collect!(request, response)
47
+ processor = Processor.new(request, response)
48
+ processor.save!
49
+
50
+ processor.record
51
+ end
52
+
53
+ # Inject the webprofiler
54
+ #
55
+ # @param body [String]
56
+ def inject(body)
57
+ body.gsub(%r{</body>}, template.result(binding) + "</body>")
58
+ end
59
+
60
+ # Get the javascript code template to inject.
61
+ #
62
+ # @return [String]
63
+ def template
64
+ @template ||= ERB.new(::File.read(::File.expand_path("../../templates/async.erb", __FILE__)))
65
+ end
66
+
67
+ class Processor
68
+ attr_reader :record
69
+
70
+ def initialize(request, response)
71
+ @collectors = {}
72
+ @request = request.clone.freeze
73
+ @response = response.clone.freeze
74
+ @record = nil
75
+ end
76
+
77
+ def save!
78
+ create_record!
79
+ save_collected_datas!
80
+
81
+ @record.save
82
+ end
83
+
84
+ private
85
+
86
+ def create_record!
87
+ @record ||= WebProfiler::Model::CollectionRecord.create({
88
+ url: @request.path,
89
+ ip: @request.ip,
90
+ http_method: @request.request_method,
91
+ http_status: @response.status,
92
+ content_type: @response.content_type,
93
+ datas: {},
94
+ })
95
+ end
96
+
97
+ def save_collected_datas!
98
+ datas = {}
99
+
100
+ Rack::WebProfiler.config.collectors.all.each do |name, definition|
101
+ datas[name.to_sym] = definition.collect!(@request, @response).to_h
102
+ end
103
+
104
+ @record.datas = datas
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,9 @@
1
+ module Rack
2
+ class WebProfiler
3
+ # ERB
4
+ class ERB
5
+ def initialize(template, layout: nil)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,45 @@
1
+ module Rack
2
+ #
3
+ class WebProfiler::Model::CollectionRecord < Sequel::Model(Rack::WebProfiler::Model.database)
4
+ # Plugins
5
+ plugin :schema
6
+ plugin :hook_class_methods
7
+ plugin :serialization
8
+ plugin :timestamps
9
+
10
+ # Attributes:
11
+ # - id
12
+ # - token
13
+ # - ip
14
+ # - url
15
+ # - http_method
16
+ # - http_status
17
+ # - content_type
18
+ # - datas
19
+ # - created_at
20
+ set_schema do
21
+ primary_key :id
22
+
23
+ varchar :token, unique: true, empty: false
24
+ varchar :url, empty: false
25
+ varchar :ip, empty: false
26
+ varchar :http_method, empty: false
27
+ integer :http_status
28
+ varchar :content_type
29
+ string :datas, text: true, empty: false
30
+ datetime :created_at
31
+ end
32
+ create_table unless table_exists?
33
+
34
+ # Serialization
35
+ serialize_attributes :marshal, :datas
36
+
37
+ # Hooks
38
+ before_create :before_create
39
+
40
+ def before_create
41
+ token = Time.now.to_f.to_s.delete(".").to_i
42
+ self.token = token.to_s(36)
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,35 @@
1
+ require "sequel"
2
+
3
+ module Rack
4
+ # Model
5
+ class WebProfiler::Model
6
+ autoload :CollectionRecord, "rack/web_profiler/model/collection_record"
7
+
8
+ class << self
9
+ # Get the WebProfiler database.
10
+ #
11
+ # @return [Sequel::SQLite::Database]
12
+ def database
13
+ @db ||= Sequel.connect("sqlite://#{db_file_path}", timeout: 50)
14
+ end
15
+
16
+ # Remove the database content.
17
+ def clean
18
+ return unless ::File.exist?(db_file_path)
19
+
20
+ ::File.delete(db_file_path)
21
+ @db = nil
22
+ @db_file_path = nil
23
+ end
24
+
25
+ private
26
+
27
+ # Returns the db file path.
28
+ #
29
+ # @return [String]
30
+ def db_file_path
31
+ @db_file_path ||= ::File.join(WebProfiler.config.tmp_dir, "rack-webprofiler.db")
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,14 @@
1
+ module Rack
2
+ #
3
+ class WebProfiler::Request < Rack::Request
4
+ attr_reader :runtime
5
+
6
+ def start_runtime!
7
+ @request_start ||= Time.now.to_f
8
+ end
9
+
10
+ def save_runtime!
11
+ @runtime ||= Time.now.to_f - @request_start
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,71 @@
1
+ module Rack
2
+ # Router
3
+ #
4
+ # Show WebProfiler page if the request path match with one
5
+ # of the webprofiler routes.
6
+ class WebProfiler::Router
7
+ BASE_PATH = "/_rwpt".freeze
8
+
9
+ class << self
10
+ # Get response for given request.
11
+ #
12
+ # @param request [Rack::WebProfiler::Request]
13
+ #
14
+ # @return [Rack::Reponse, false]
15
+ def response_for(request)
16
+ @request = request
17
+ path = Rack::Utils.unescape(request.path_info)
18
+
19
+ # Stop process if the request path does not start
20
+ # by the BASE_PATH
21
+ return false unless path.start_with?(BASE_PATH)
22
+
23
+ path.slice!(BASE_PATH)
24
+
25
+ route(request, path)
26
+ end
27
+
28
+ # Route!
29
+ def route(request, path)
30
+ controller = WebProfiler::Controller.new(request)
31
+
32
+ if request.get? && path =~ %r{^\/toolbar\/([a-z0-9]*)(\/)?$}
33
+ controller.show_toolbar(Regexp.last_match(1))
34
+ elsif request.get? && path =~ %r{^\/clean(\/)?$}
35
+ controller.delete
36
+ elsif request.get? && path =~ %r{^(\/)?$}
37
+ controller.index
38
+ elsif request.get? && path =~ %r{^\/([a-z0-9]*)(\/)?$}
39
+ controller.show(Regexp.last_match(1))
40
+ else
41
+ false
42
+ end
43
+ end
44
+
45
+ # Get url for toobar.
46
+ #
47
+ # @param token [String]
48
+ #
49
+ # @return [String]
50
+ def url_for_toolbar(token)
51
+ "#{@request.script_name}#{BASE_PATH}/toolbar/#{token}"
52
+ end
53
+
54
+ # Get url for the webprofiler.
55
+ #
56
+ # @param token [String, nil]
57
+ #
58
+ # @return [String]
59
+ def url_for_profiler(token = nil)
60
+ "#{@request.script_name}#{BASE_PATH}/#{token}"
61
+ end
62
+
63
+ # Get url to clean webprofiler.
64
+ #
65
+ # @return [String]
66
+ def url_for_clean_profiler
67
+ "#{@request.script_name}#{BASE_PATH}/clean"
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,5 @@
1
+ module Rack
2
+ class WebProfiler
3
+ VERSION = "0.1.0-alpha1".freeze
4
+ end
5
+ end