rack-mini-profiler 0.1.7 → 0.1.12.pre

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rack-mini-profiler might be problematic. Click here for more details.

data/CHANGELOG CHANGED
@@ -24,3 +24,31 @@
24
24
  * Added some more client probing built in to rails
25
25
  * More tests
26
26
 
27
+ 18-July-2012 - Sam
28
+
29
+ * Added First Paint time for chrome
30
+ * Bug fix to ensure non Rails installs have mini profiler
31
+ * Version 0.1.7
32
+
33
+ 30-July-2012 - Sam
34
+
35
+ * Made compliant with ancient versions of Rack (including Rack used by Rails2)
36
+ * Fixed broken share link
37
+ * Fixed crashes on startup (in MemoryStore and FileStore)
38
+ * Version 0.1.8
39
+ * Unicode fix
40
+ * Version 0.1.9
41
+
42
+ 7-August-2012 - Sam
43
+
44
+ * Added option to disable profiler for the current session (pp=disable / pp=enable)
45
+ * yajl compatability contributed by Sven Riedel
46
+
47
+ 10-August-2012 - Sam
48
+
49
+ * Added basic prepared statement profiling for postgres
50
+
51
+ 20-August-2012 - Sam
52
+
53
+ * 1.12.pre
54
+ * Cap X-MiniProfiler-Ids at 10, otherwise the header can get killed
data/README.md CHANGED
@@ -47,6 +47,24 @@ class MyApp < Sinatra::Base
47
47
  end
48
48
  ```
49
49
 
50
+ ## Storage
51
+
52
+ By default, rack-mini-profiler stores its results in a memory store:
53
+
54
+ ```ruby
55
+ # our default
56
+ Rack::MiniProfiler.config.storage = Rack::MiniProfiler::MemoryStore
57
+ ```
58
+
59
+ There are 2 other available storage engines, `RedisStore` and `FileStore`.
60
+
61
+ MemoryStore is stores results in a processes heap - something that does not work well in a multi process environment.
62
+ FileStore stores results in the file system - something that may not work well in a multi machine environment.
63
+
64
+ Additionally you may implement an AbstractStore for your own provider.
65
+
66
+ Rails hooks up a FileStore for all environments.
67
+
50
68
  ## Running the Specs
51
69
 
52
70
  ```
@@ -67,11 +85,18 @@ Rack::MiniProfiler.config.position = 'right'
67
85
 
68
86
  In a Rails app, this can be done conveniently in an initializer such as config/initializers/mini_profiler.rb.
69
87
 
88
+ ## Rails 2.X support
89
+
90
+ MiniProfiler uses [railtie](https://github.com/SamSaffron/MiniProfiler/blob/master/Ruby/lib/mini_profiler_rails/railtie.rb) to bootstrap itself. This will not be called in a Rails 2 app. You are going to need to hook it up manually. (TODO: document this - pull request please)
91
+
70
92
  ## Available Options
71
93
 
72
94
  * pre_authorize_cb - A lambda callback you can set to determine whether or not mini_profiler should be visible on a given request. Default in a Rails environment is only on in development mode. If in a Rack app, the default is always on.
73
95
  * position - Can either be 'right' or 'left'. Default is 'left'.
74
96
  * skip_schema_queries - Whether or not you want to log the queries about the schema of your tables. Default is 'false', 'true' in rails development.
97
+ * use_existing_jquery - Use the version of jQuery on the page as opposed to the self contained one
98
+ * auto_inject (default true) - when false the miniprofiler script is not injected in the page
99
+ * backtrace_filter - a regex you can use to filter out unwanted lines from the backtraces
75
100
 
76
101
  ## Special query strings
77
102
 
@@ -1,6 +1,6 @@
1
- <script type="text/javascript">
1
+ <script type="text/javascript">
2
2
  (function(){{
3
- var init = function() {{
3
+ var init = function() {{
4
4
  var load = function(s,f){{
5
5
  var sc = document.createElement('script');
6
6
  sc.async = 'async';
@@ -14,8 +14,8 @@
14
14
  }};
15
15
 
16
16
  document.getElementsByTagName('head')[0].appendChild(sc);
17
- }};
18
-
17
+ }};
18
+
19
19
  var initMp = function(){{
20
20
  load('{path}includes.js?v={version}',function(){{
21
21
  MiniProfiler.init({{
@@ -32,18 +32,18 @@
32
32
  }});
33
33
  }});
34
34
  }};
35
- if ({useExistingjQuery}) {{
35
+ if ({useExistingjQuery} && typeof(jQuery) === 'function') {{
36
36
  jQueryMP = jQuery;
37
37
  initMp();
38
38
  }} else {{
39
39
  load('{path}jquery.1.7.1.js?v={version}', initMp);
40
40
  }}
41
-
41
+
42
42
  }};
43
43
 
44
- var w = 0;
44
+ var w = 0;
45
45
  var f = false;
46
- var deferInit = function(){{
46
+ var deferInit = function(){{
47
47
  if (f) return;
48
48
  if (window.performance && window.performance.timing && window.performance.timing.loadEventEnd == 0 && w < 10000){{
49
49
  setTimeout(deferInit, 100);
@@ -59,4 +59,4 @@
59
59
  var o = window.onload;
60
60
  window.onload = function(){{if(o)o; deferInit()}};
61
61
  }})();
62
- </script>
62
+ </script>
@@ -0,0 +1,11 @@
1
+ <html>
2
+ <head>
3
+ <title>{name} ({duration} ms) - Profiling Results</title>
4
+ <script type='text/javascript' src='{path}jquery.1.7.1.js?v={version}'></script>
5
+ <script type='text/javascript'> var profiler = {json}; </script>
6
+ {includes}
7
+ </head>
8
+ <body>
9
+ <div class='profiler-result-full'></div>
10
+ </body>
11
+ </html>
@@ -23,7 +23,7 @@ module Rack
23
23
  super
24
24
  end
25
25
 
26
- def init_from_form_data(env, page_struct)
26
+ def self.init_from_form_data(env, page_struct)
27
27
  timings = []
28
28
  clientTimes, clientPerf, baseTime = nil
29
29
  form = env['rack.request.form_hash']
@@ -67,8 +67,10 @@ module Rack
67
67
  timings.push("Name" => k, "Start" => clientTimes[k].to_i - baseTime, "Duration" => -1)
68
68
  end
69
69
 
70
- self['RedirectCount'] = env['rack.request.form_hash']['clientPerformance']['navigation']['redirectCount']
71
- self['Timings'] = timings
70
+ rval = self.new
71
+ rval['RedirectCount'] = env['rack.request.form_hash']['clientPerformance']['navigation']['redirectCount']
72
+ rval['Timings'] = timings
73
+ rval
72
74
  end
73
75
  end
74
76
 
@@ -14,7 +14,7 @@ module Rack
14
14
 
15
15
  attr_accessor :auto_inject, :base_url_path, :pre_authorize_cb, :position,
16
16
  :backtrace_remove, :backtrace_filter, :skip_schema_queries,
17
- :storage, :user_provider, :storage_instance, :storage_options, :skip_paths, :authorization_mode
17
+ :storage, :user_provider, :storage_instance, :storage_options, :skip_paths, :authorization_mode, :use_existing_jquery
18
18
 
19
19
  def self.default
20
20
  new.instance_eval {
@@ -30,6 +30,7 @@ module Rack
30
30
  @storage = MiniProfiler::MemoryStore
31
31
  @user_provider = Proc.new{|env| Rack::Request.new(env).ip}
32
32
  @authorization_mode = :allow_all
33
+ @use_existing_jquery = false
33
34
  self
34
35
  }
35
36
  end
@@ -16,7 +16,7 @@ module Rack
16
16
  "Level" => 0,
17
17
  "User" => "unknown user",
18
18
  "HasUserViewed" => false,
19
- "ClientTimings" => ClientTimerStruct.new,
19
+ "ClientTimings" => nil,
20
20
  "DurationMilliseconds" => 0,
21
21
  "HasTrivialTimings" => true,
22
22
  "HasAllTrivialTimigs" => false,
@@ -6,7 +6,6 @@ require 'mini_profiler/page_timer_struct'
6
6
  require 'mini_profiler/sql_timer_struct'
7
7
  require 'mini_profiler/client_timer_struct'
8
8
  require 'mini_profiler/request_timer_struct'
9
- require 'mini_profiler/body_add_proxy'
10
9
  require 'mini_profiler/storage/abstract_store'
11
10
  require 'mini_profiler/storage/memory_store'
12
11
  require 'mini_profiler/storage/redis_store'
@@ -64,11 +63,26 @@ module Rack
64
63
 
65
64
  # remove the mini profiler cookie, only used when config.authorization_mode == :whitelist
66
65
  def remove_profiling_cookie(headers)
67
- Rack::Utils.delete_cookie_header!(headers, '__profilin')
66
+ Rack::Utils.set_cookie_header!(headers, '__profilin', :value => 'notstylin', :path => '/')
68
67
  end
69
68
 
70
69
  def set_profiling_cookie(headers)
71
- Rack::Utils.set_cookie_header!(headers, '__profilin', 'stylin')
70
+ Rack::Utils.set_cookie_header!(headers, '__profilin', :value => 'stylin', :path => '/')
71
+ end
72
+
73
+ # user has the mini profiler cookie, only used when config.authorization_mode == :whitelist
74
+ def has_disable_profiling_cookie?(env)
75
+ env['HTTP_COOKIE'] && env['HTTP_COOKIE'].include?("__profilin_disable=stylin")
76
+ end
77
+
78
+ # remove the mini profiler cookie, only used when config.authorization_mode == :whitelist
79
+ def remove_disable_profiling_cookie(headers)
80
+ #something is odd with delete_cookie_header
81
+ Rack::Utils.set_cookie_header!(headers, '__profilin_disable', :value => 'notstylin', :path => '/')
82
+ end
83
+
84
+ def set_disable_profiling_cookie(headers)
85
+ Rack::Utils.set_cookie_header!(headers, '__profilin_disable', :value => 'stylin', :path => '/')
72
86
  end
73
87
 
74
88
  def create_current(env={}, options={})
@@ -101,8 +115,9 @@ module Rack
101
115
  @app = app
102
116
  @config.base_url_path << "/" unless @config.base_url_path.end_with? "/"
103
117
  unless @config.storage_instance
104
- @storage = @config.storage_instance = @config.storage.new(@config.storage_options)
118
+ @config.storage_instance = @config.storage.new(@config.storage_options)
105
119
  end
120
+ @storage = @config.storage_instance
106
121
  end
107
122
 
108
123
  def user(env)
@@ -118,7 +133,7 @@ module Rack
118
133
  return [404, {}, ["Request not found: #{request['id']} - user #{user(env)}"]]
119
134
  end
120
135
  unless page_struct['HasUserViewed']
121
- page_struct['ClientTimings'].init_from_form_data(env, page_struct)
136
+ page_struct['ClientTimings'] = ClientTimerStruct.init_from_form_data(env, page_struct)
122
137
  page_struct['HasUserViewed'] = true
123
138
  @storage.save(page_struct)
124
139
  @storage.set_viewed(user(env), id)
@@ -151,8 +166,17 @@ module Rack
151
166
  return [404, {}, ["Not found"]] unless ::File.exists? full_path
152
167
  f = Rack::File.new nil
153
168
  f.path = full_path
154
- f.cache_control = "max-age:86400"
155
- f.serving env
169
+
170
+ begin
171
+ f.cache_control = "max-age:86400"
172
+ f.serving env
173
+ rescue
174
+ # old versions of rack have a different api
175
+ status, headers, body = f.serving
176
+ headers.merge! 'Cache-Control' => "max-age:86400"
177
+ [status, headers, body]
178
+ end
179
+
156
180
  end
157
181
 
158
182
 
@@ -172,11 +196,12 @@ module Rack
172
196
 
173
197
  def call(env)
174
198
  status = headers = body = nil
199
+ query_string = env['QUERY_STRING']
175
200
  path = env['PATH_INFO']
176
201
 
177
202
  skip_it = (@config.pre_authorize_cb && !@config.pre_authorize_cb.call(env)) ||
178
203
  (@config.skip_paths && @config.skip_paths.any?{ |p| path[0,p.length] == p}) ||
179
- env["QUERY_STRING"] =~ /pp=skip/
204
+ query_string =~ /pp=skip/
180
205
 
181
206
  has_profiling_cookie = MiniProfiler.has_profiling_cookie?(env)
182
207
 
@@ -189,13 +214,29 @@ module Rack
189
214
  end
190
215
 
191
216
  # handle all /mini-profiler requests here
192
- return serve_html(env) if env['PATH_INFO'].start_with? @config.base_url_path
217
+ return serve_html(env) if path.start_with? @config.base_url_path
218
+
219
+ has_disable_cookie = MiniProfiler.has_disable_profiling_cookie?(env)
220
+ # manual session disable / enable
221
+ if query_string =~ /pp=disable/ || has_disable_cookie
222
+ skip_it = true
223
+ end
224
+
225
+ if query_string =~ /pp=enable/
226
+ skip_it = false
227
+ end
228
+
229
+ if skip_it
230
+ status,headers,body = @app.call(env)
231
+ MiniProfiler.set_disable_profiling_cookie(headers) unless has_disable_cookie
232
+ return [status,headers,body]
233
+ end
193
234
 
194
235
  MiniProfiler.create_current(env, @config)
195
236
  MiniProfiler.deauthorize_request if @config.authorization_mode == :whitelist
196
- if env["QUERY_STRING"] =~ /pp=no-backtrace/
237
+ if query_string =~ /pp=no-backtrace/
197
238
  current.skip_backtrace = true
198
- elsif env["QUERY_STRING"] =~ /pp=full-backtrace/
239
+ elsif query_string =~ /pp=full-backtrace/
199
240
  current.full_backtrace = true
200
241
  end
201
242
 
@@ -203,7 +244,7 @@ module Rack
203
244
  quit_sampler = false
204
245
  backtraces = nil
205
246
  missing_stacktrace = false
206
- if env["QUERY_STRING"] =~ /pp=sample/
247
+ if query_string =~ /pp=sample/
207
248
  backtraces = []
208
249
  t = Thread.current
209
250
  Thread.new {
@@ -231,6 +272,9 @@ module Rack
231
272
  start = Time.now
232
273
  begin
233
274
  status,headers,body = @app.call(env)
275
+ if has_disable_cookie
276
+ MiniProfiler.remove_disable_profiling_cookie(headers)
277
+ end
234
278
  ensure
235
279
  if backtraces
236
280
  done_sampling = true
@@ -245,14 +289,14 @@ module Rack
245
289
  end
246
290
 
247
291
  return [status,headers,body] if skip_it
248
-
292
+
249
293
  # we must do this here, otherwise current[:discard] is not being properly treated
250
- if env["QUERY_STRING"] =~ /pp=env/
294
+ if query_string =~ /pp=env/
251
295
  body.close if body.respond_to? :close
252
296
  return dump_env env
253
297
  end
254
298
 
255
- if env["QUERY_STRING"] =~ /pp=help/
299
+ if query_string =~ /pp=help/
256
300
  body.close if body.respond_to? :close
257
301
  return help
258
302
  end
@@ -274,6 +318,12 @@ module Rack
274
318
  # inject headers, script
275
319
  if status == 200
276
320
 
321
+ # mini profiler is meddling with stuff, we can not cache cause we will get incorrect data
322
+ # Rack::ETag has already inserted some nonesense in the chain
323
+ headers.delete('ETag')
324
+ headers.delete('Date')
325
+ headers['Cache-Control'] = 'must-revalidate, private, max-age=0'
326
+
277
327
  # inject header
278
328
  if headers.is_a? Hash
279
329
  headers['X-MiniProfiler-Ids'] = ids_json(env)
@@ -283,21 +333,37 @@ module Rack
283
333
  if current.inject_js \
284
334
  && headers.has_key?('Content-Type') \
285
335
  && !headers['Content-Type'].match(/text\/html/).nil? then
286
- body = MiniProfiler::BodyAddProxy.new(body, self.get_profile_script(env))
336
+
337
+ response = Rack::Response.new([], status, headers)
338
+ script = self.get_profile_script(env)
339
+ if String === body
340
+ response.write inject(body,script)
341
+ else
342
+ body.each { |fragment| response.write inject(fragment, script) }
343
+ end
344
+ body.close if body.respond_to? :close
345
+ return response.finish
287
346
  end
288
347
  end
289
348
 
290
- # mini profiler is meddling with stuff, we can not cache cause we will get incorrect data
291
- # Rack::ETag has already inserted some nonesense in the chain
292
- headers.delete('ETag')
293
- headers.delete('Date')
294
- headers['Cache-Control'] = 'must-revalidate, private, max-age=0'
295
349
  [status, headers, body]
296
350
  ensure
297
351
  # Make sure this always happens
298
352
  current = nil
299
353
  end
300
354
 
355
+ def inject(fragment, script)
356
+ fragment.sub(/<\/body>/i) do
357
+ # if for whatever crazy reason we dont get a utf string,
358
+ # just force the encoding, no utf in the mp scripts anyway
359
+ if script.respond_to?(:encoding) && script.respond_to?(:force_encoding)
360
+ (script + "</body>").force_encoding(fragment.encoding)
361
+ else
362
+ script + "</body>"
363
+ end
364
+ end
365
+ end
366
+
301
367
  def dump_env(env)
302
368
  headers = {'Content-Type' => 'text/plain'}
303
369
  body = ""
@@ -317,6 +383,8 @@ module Rack
317
383
  pp=no-backtrace : don't collect stack traces from all the SQL executed
318
384
  pp=full-backtrace : enable full backtrace for SQL executed
319
385
  pp=sample : sample stack traces and return a report isolating heavy usage (requires the stacktrace gem)
386
+ pp=disable : disable profiling for this session
387
+ pp=enable : enable profiling for this session (if previously disabled)
320
388
  "
321
389
  if (category == :stacktrace)
322
390
  body = "pp=stacktrace requires the stacktrace gem - add gem 'stacktrace' to your Gemfile"
@@ -359,7 +427,8 @@ module Rack
359
427
  end
360
428
 
361
429
  def ids_json(env)
362
- ids = [current.page_struct["Id"]] + (@storage.get_unviewed_ids(user(env)) || [])
430
+ # cap at 10 ids, otherwise there is a chance you can blow the header
431
+ ids = [current.page_struct["Id"]] + (@storage.get_unviewed_ids(user(env)) || [])[0..8]
363
432
  ::JSON.generate(ids.uniq)
364
433
  end
365
434
 
@@ -380,7 +449,7 @@ module Rack
380
449
  showControls = false
381
450
  currentId = current.page_struct["Id"]
382
451
  authorized = true
383
- useExistingjQuery = false
452
+ useExistingjQuery = @config.use_existing_jquery
384
453
  # TODO : cache this snippet
385
454
  script = IO.read(::File.expand_path('../html/profile_handler.js', ::File.dirname(__FILE__)))
386
455
  # replace the variables
@@ -39,9 +39,14 @@ module Rack
39
39
 
40
40
  me = self
41
41
  Thread.new do
42
- while true do
43
- me.cleanup_cache if MiniProfiler.instance
44
- sleep(3600)
42
+ begin
43
+ while true do
44
+ # TODO: a sane retry count before bailing
45
+ me.cleanup_cache
46
+ sleep(3600)
47
+ end
48
+ rescue
49
+ # don't crash the thread, we can clean up next time
45
50
  end
46
51
  end
47
52
  end
@@ -83,10 +88,6 @@ module Rack
83
88
  }
84
89
  end
85
90
 
86
-
87
- private
88
-
89
-
90
91
  def cleanup_cache
91
92
  files = Dir.entries(@path)
92
93
  @timer_struct_lock.synchronize {
@@ -52,10 +52,6 @@ module Rack
52
52
  }
53
53
  end
54
54
 
55
-
56
- private
57
-
58
-
59
55
  def cleanup_cache
60
56
  expire_older_than = ((Time.now.to_f - MiniProfiler::MemoryStore::EXPIRE_TIMER_CACHE) * 1000).to_i
61
57
  @timer_struct_lock.synchronize {
@@ -22,7 +22,9 @@ module Rack
22
22
  end
23
23
 
24
24
  def to_json(*a)
25
- ::JSON.generate(@attributes, a[0])
25
+ # this does could take in an option hash, but the only interesting there is max_nesting.
26
+ # if this becomes an option we could increase
27
+ ::JSON.generate( @attributes, :max_nesting => 100 )
26
28
  end
27
29
 
28
30
  end
@@ -1,3 +1,5 @@
1
+ require 'fileutils'
2
+
1
3
  module MiniProfilerRails
2
4
 
3
5
  class Railtie < ::Rails::Railtie
@@ -22,7 +24,7 @@ module MiniProfilerRails
22
24
 
23
25
  # The file store is just so much less flaky
24
26
  tmp = Rails.root.to_s + "/tmp/miniprofiler"
25
- Dir::mkdir(tmp) unless File.exists?(tmp)
27
+ FileUtils.mkdir_p(tmp) unless File.exists?(tmp)
26
28
 
27
29
  c.storage_options = {:path => tmp}
28
30
  c.storage = Rack::MiniProfiler::FileStore
@@ -91,6 +91,23 @@ if SqlPatches.class_exists? "PG::Result"
91
91
  class PG::Connection
92
92
  alias_method :exec_without_profiling, :exec
93
93
  alias_method :async_exec_without_profiling, :async_exec
94
+ alias_method :exec_prepared_without_profiling, :exec_prepared
95
+ alias_method :send_query_prepared_without_profiling, :send_query_prepared
96
+ alias_method :prepare_without_profiling, :prepare
97
+
98
+ def prepare(*args,&blk)
99
+ current = ::Rack::MiniProfiler.current
100
+ return prepare_without_profiling(*args,&blk) unless current
101
+
102
+ @prepare_map ||= {}
103
+ @prepare_map[args[0]] = args[1]
104
+
105
+ # dont leak more than 10k ever
106
+ @prepare_map = {} if @prepare_map.length > 10000
107
+
108
+ prepare_without_profiling(*args,&blk)
109
+
110
+ end
94
111
 
95
112
  def exec(*args,&blk)
96
113
  current = ::Rack::MiniProfiler.current
@@ -104,6 +121,34 @@ if SqlPatches.class_exists? "PG::Result"
104
121
  result
105
122
  end
106
123
 
124
+ def exec_prepared(*args,&blk)
125
+ current = ::Rack::MiniProfiler.current
126
+ return exec_prepared_without_profiling(*args,&blk) unless current
127
+
128
+ start = Time.now
129
+ result = exec_prepared_without_profiling(*args,&blk)
130
+ elapsed_time = ((Time.now - start).to_f * 1000).round(1)
131
+ mapped = args[0]
132
+ mapped = @prepare_map[mapped] || args[0] if @prepare_map
133
+ result.instance_variable_set("@miniprofiler_sql_id", ::Rack::MiniProfiler.record_sql(mapped, elapsed_time))
134
+
135
+ result
136
+ end
137
+
138
+ def send_query_prepared(*args,&blk)
139
+ current = ::Rack::MiniProfiler.current
140
+ return send_query_prepared_without_profiling(*args,&blk) unless current
141
+
142
+ start = Time.now
143
+ result = send_query_prepared_without_profiling(*args,&blk)
144
+ elapsed_time = ((Time.now - start).to_f * 1000).round(1)
145
+ mapped = args[0]
146
+ mapped = @prepare_map[mapped] || args[0] if @prepare_map
147
+ result.instance_variable_set("@miniprofiler_sql_id", ::Rack::MiniProfiler.record_sql(mapped, elapsed_time))
148
+
149
+ result
150
+ end
151
+
107
152
  def async_exec(*args,&blk)
108
153
  current = ::Rack::MiniProfiler.current
109
154
  return exec_without_profiling(*args,&blk) unless current
@@ -1,6 +1,6 @@
1
- require File.expand_path('mini_profiler/profiler', File.dirname(__FILE__) )
2
- require File.expand_path('patches/sql_patches', File.dirname(__FILE__) )
1
+ require 'mini_profiler/profiler'
2
+ require 'patches/sql_patches'
3
3
 
4
4
  if defined?(::Rails) && ::Rails::VERSION::MAJOR.to_i == 3
5
- require File.expand_path('mini_profiler_rails/railtie', File.dirname(__FILE__) )
5
+ require 'mini_profiler_rails/railtie'
6
6
  end
@@ -1,9 +1,8 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "rack-mini-profiler"
3
- s.version = "0.1.7"
3
+ s.version = "0.1.12.pre"
4
4
  s.summary = "Profiles loading speed for rack applications."
5
5
  s.authors = ["Aleks Totic","Sam Saffron", "Robin Ward"]
6
- s.date = "2012-04-02"
7
6
  s.description = "Page loading speed displayed on every page. Optimize while you develop, performance is a feature."
8
7
  s.email = "sam.saffron@gmail.com"
9
8
  s.homepage = "http://miniprofiler.com"
@@ -14,9 +13,9 @@ Gem::Specification.new do |s|
14
13
  "README.md",
15
14
  "CHANGELOG"
16
15
  ]
17
- s.add_runtime_dependency 'rack', '>= 1.1.3'
16
+ s.add_runtime_dependency 'rack', '>= 1.1.3'
18
17
  if RUBY_VERSION < "1.9"
19
- s.add_runtime_dependency 'json', '>= 1.6'
18
+ s.add_runtime_dependency 'json', '>= 1.6'
20
19
  end
21
20
 
22
21
  s.add_development_dependency 'rake'
metadata CHANGED
@@ -1,8 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-mini-profiler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.7
5
- prerelease:
4
+ version: 0.1.12.pre
5
+ prerelease: 7
6
6
  platform: ruby
7
7
  authors:
8
8
  - Aleks Totic
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2012-04-02 00:00:00.000000000 Z
14
+ date: 2012-08-19 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: rack
@@ -93,7 +93,6 @@ files:
93
93
  - lib/mini_profiler/page_timer_struct.rb
94
94
  - lib/mini_profiler/context.rb
95
95
  - lib/mini_profiler/config.rb
96
- - lib/mini_profiler/body_add_proxy.rb
97
96
  - lib/mini_profiler/profiling_methods.rb
98
97
  - lib/mini_profiler/client_timer_struct.rb
99
98
  - lib/mini_profiler/profiler.rb
@@ -104,6 +103,7 @@ files:
104
103
  - lib/rack-mini-profiler.rb
105
104
  - lib/html/jquery.1.7.1.js
106
105
  - lib/html/includes.tmpl
106
+ - lib/html/share.html
107
107
  - lib/html/includes.less
108
108
  - lib/html/list.css
109
109
  - lib/html/includes.js
@@ -130,16 +130,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
130
130
  version: '0'
131
131
  segments:
132
132
  - 0
133
- hash: -348401747
133
+ hash: -1045845709
134
134
  required_rubygems_version: !ruby/object:Gem::Requirement
135
135
  none: false
136
136
  requirements:
137
- - - ! '>='
137
+ - - ! '>'
138
138
  - !ruby/object:Gem::Version
139
- version: '0'
140
- segments:
141
- - 0
142
- hash: -348401747
139
+ version: 1.3.1
143
140
  requirements: []
144
141
  rubyforge_project:
145
142
  rubygems_version: 1.8.24
@@ -1,45 +0,0 @@
1
- module Rack
2
- class MiniProfiler
3
-
4
- # This class acts as a proxy to the Body so that we can
5
- # safely append to the end without knowing about the internals
6
- # of the body class.
7
- class BodyAddProxy
8
- def initialize(body, additional_text)
9
- @body = body
10
- @additional_text = additional_text
11
- end
12
-
13
- def respond_to?(*args)
14
- super or @body.respond_to?(*args)
15
- end
16
-
17
- def method_missing(*args, &block)
18
- @body.__send__(*args, &block)
19
- end
20
-
21
- # In the case of to_str we don't want to use method_missing as it might avoid
22
- # a call to each (such as in Rack::Test)
23
- def to_str
24
- result = ""
25
- each {|token| result << token}
26
- result
27
- end
28
-
29
- def each(&block)
30
-
31
- # In ruby 1.9 we don't support String#each
32
- if @body.is_a?(String)
33
- yield @body
34
- else
35
- @body.each(&block)
36
- end
37
-
38
- yield @additional_text
39
- self
40
- end
41
-
42
- end
43
-
44
- end
45
- end