ghazel-rack-bug 0.3.0.1

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.
Files changed (86) hide show
  1. data/.gitignore +3 -0
  2. data/History.txt +45 -0
  3. data/MIT-LICENSE.txt +19 -0
  4. data/README.md +118 -0
  5. data/Rakefile +23 -0
  6. data/Thorfile +113 -0
  7. data/lib/rack/bug.rb +83 -0
  8. data/lib/rack/bug/autoloading.rb +24 -0
  9. data/lib/rack/bug/filtered_backtrace.rb +38 -0
  10. data/lib/rack/bug/options.rb +89 -0
  11. data/lib/rack/bug/panel.rb +50 -0
  12. data/lib/rack/bug/panel_app.rb +33 -0
  13. data/lib/rack/bug/panels/active_record_panel.rb +45 -0
  14. data/lib/rack/bug/panels/active_record_panel/activerecord_extensions.rb +18 -0
  15. data/lib/rack/bug/panels/cache_panel.rb +51 -0
  16. data/lib/rack/bug/panels/cache_panel/dalli_extension.rb +16 -0
  17. data/lib/rack/bug/panels/cache_panel/memcache_extension.rb +129 -0
  18. data/lib/rack/bug/panels/cache_panel/panel_app.rb +48 -0
  19. data/lib/rack/bug/panels/cache_panel/stats.rb +97 -0
  20. data/lib/rack/bug/panels/log_panel.rb +56 -0
  21. data/lib/rack/bug/panels/log_panel/logger_extension.rb +24 -0
  22. data/lib/rack/bug/panels/memory_panel.rb +27 -0
  23. data/lib/rack/bug/panels/rails_info_panel.rb +23 -0
  24. data/lib/rack/bug/panels/redis_panel.rb +44 -0
  25. data/lib/rack/bug/panels/redis_panel/redis_extension.rb +28 -0
  26. data/lib/rack/bug/panels/redis_panel/stats.rb +52 -0
  27. data/lib/rack/bug/panels/request_variables_panel.rb +52 -0
  28. data/lib/rack/bug/panels/sphinx_panel.rb +44 -0
  29. data/lib/rack/bug/panels/sphinx_panel/sphinx_extension.rb +25 -0
  30. data/lib/rack/bug/panels/sphinx_panel/stats.rb +96 -0
  31. data/lib/rack/bug/panels/sql_panel.rb +55 -0
  32. data/lib/rack/bug/panels/sql_panel/panel_app.rb +37 -0
  33. data/lib/rack/bug/panels/sql_panel/query.rb +63 -0
  34. data/lib/rack/bug/panels/sql_panel/sql_extension.rb +11 -0
  35. data/lib/rack/bug/panels/templates_panel.rb +44 -0
  36. data/lib/rack/bug/panels/templates_panel/actionview_extension.rb +12 -0
  37. data/lib/rack/bug/panels/templates_panel/rendering.rb +67 -0
  38. data/lib/rack/bug/panels/templates_panel/trace.rb +34 -0
  39. data/lib/rack/bug/panels/timer_panel.rb +40 -0
  40. data/lib/rack/bug/params_signature.rb +63 -0
  41. data/lib/rack/bug/public/__rack_bug__/bookmarklet.html +10 -0
  42. data/lib/rack/bug/public/__rack_bug__/bookmarklet.js +217 -0
  43. data/lib/rack/bug/public/__rack_bug__/bug.css +216 -0
  44. data/lib/rack/bug/public/__rack_bug__/bug.js +84 -0
  45. data/lib/rack/bug/public/__rack_bug__/jquery-1.3.2.js +4376 -0
  46. data/lib/rack/bug/public/__rack_bug__/jquery.tablesorter.min.js +1 -0
  47. data/lib/rack/bug/public/__rack_bug__/spinner.gif +0 -0
  48. data/lib/rack/bug/rack_static_bug_avoider.rb +16 -0
  49. data/lib/rack/bug/redirect_interceptor.rb +27 -0
  50. data/lib/rack/bug/render.rb +66 -0
  51. data/lib/rack/bug/toolbar.rb +66 -0
  52. data/lib/rack/bug/views/error.html.erb +16 -0
  53. data/lib/rack/bug/views/panels/active_record.html.erb +17 -0
  54. data/lib/rack/bug/views/panels/cache.html.erb +93 -0
  55. data/lib/rack/bug/views/panels/execute_sql.html.erb +32 -0
  56. data/lib/rack/bug/views/panels/explain_sql.html.erb +32 -0
  57. data/lib/rack/bug/views/panels/log.html.erb +21 -0
  58. data/lib/rack/bug/views/panels/profile_sql.html.erb +32 -0
  59. data/lib/rack/bug/views/panels/rails_info.html.erb +19 -0
  60. data/lib/rack/bug/views/panels/redis.html.erb +46 -0
  61. data/lib/rack/bug/views/panels/request_variables.html.erb +29 -0
  62. data/lib/rack/bug/views/panels/sphinx.html.erb +32 -0
  63. data/lib/rack/bug/views/panels/sql.html.erb +43 -0
  64. data/lib/rack/bug/views/panels/templates.html.erb +7 -0
  65. data/lib/rack/bug/views/panels/timer.html.erb +19 -0
  66. data/lib/rack/bug/views/panels/view_cache.html.erb +19 -0
  67. data/lib/rack/bug/views/redirect.html.erb +16 -0
  68. data/lib/rack/bug/views/toolbar.html.erb +42 -0
  69. data/rack-bug.gemspec +147 -0
  70. data/spec/fixtures/config.ru +8 -0
  71. data/spec/fixtures/dummy_panel.rb +2 -0
  72. data/spec/fixtures/sample_app.rb +46 -0
  73. data/spec/rack/bug/panels/active_record_panel_spec.rb +30 -0
  74. data/spec/rack/bug/panels/cache_panel_spec.rb +167 -0
  75. data/spec/rack/bug/panels/log_panel_spec.rb +43 -0
  76. data/spec/rack/bug/panels/memory_panel_spec.rb +22 -0
  77. data/spec/rack/bug/panels/rails_info_panel_spec.rb +40 -0
  78. data/spec/rack/bug/panels/redis_panel_spec.rb +69 -0
  79. data/spec/rack/bug/panels/sql_panel_spec.rb +146 -0
  80. data/spec/rack/bug/panels/templates_panel_spec.rb +71 -0
  81. data/spec/rack/bug/panels/timer_panel_spec.rb +38 -0
  82. data/spec/rack/bug_spec.rb +137 -0
  83. data/spec/rcov.opts +1 -0
  84. data/spec/spec.opts +1 -0
  85. data/spec/spec_helper.rb +44 -0
  86. metadata +201 -0
@@ -0,0 +1,40 @@
1
+ require "benchmark"
2
+
3
+ module Rack
4
+ class Bug
5
+
6
+ class TimerPanel < Panel
7
+
8
+ def name
9
+ "timer"
10
+ end
11
+
12
+ def call(env)
13
+ status, headers, body = nil
14
+ @times = Benchmark.measure do
15
+ status, headers, body = @app.call(env)
16
+ end
17
+
18
+ @measurements = [
19
+ ["User CPU time", "%.2fms" % (@times.utime * 1_000)],
20
+ ["System CPU time", "%.2fms" % (@times.stime * 1_000)],
21
+ ["Total CPU time", "%.2fms" % (@times.total * 1_000)],
22
+ ["Elapsed time", "%.2fms" % (@times.real * 1_000)]
23
+ ]
24
+
25
+ env["rack-bug.panels"] << self
26
+ return [status, headers, body]
27
+ end
28
+
29
+ def heading
30
+ "%.2fms" % (@times.real * 1_000)
31
+ end
32
+
33
+ def content
34
+ render_template "panels/timer", :measurements => @measurements
35
+ end
36
+
37
+ end
38
+
39
+ end
40
+ end
@@ -0,0 +1,63 @@
1
+ require "digest"
2
+
3
+ module Rack
4
+ class Bug
5
+
6
+ class ParamsSignature
7
+ extend ERB::Util
8
+
9
+ def self.sign(request, hash)
10
+ parts = []
11
+
12
+ hash.keys.sort.each do |key|
13
+ parts << "#{key}=#{u(hash[key])}"
14
+ end
15
+
16
+ signature = new(request).signature(hash)
17
+ parts << "hash=#{u(signature)}"
18
+
19
+ parts.join("&amp;")
20
+ end
21
+
22
+ attr_reader :request
23
+
24
+ def initialize(request)
25
+ @request = request
26
+ end
27
+
28
+ def secret_key
29
+ @request.env['rack-bug.secret_key']
30
+ end
31
+
32
+ def secret_key_blank?
33
+ secret_key.nil? || secret_key == ""
34
+ end
35
+
36
+ def validate!
37
+ if secret_key_blank?
38
+ raise SecurityError.new("Missing secret key")
39
+ elsif request.params["hash"] != signature(request.params)
40
+ raise SecurityError.new("Invalid query hash.")
41
+ end
42
+ end
43
+
44
+ def signature(params)
45
+ Digest::SHA1.hexdigest(signature_base(params))
46
+ end
47
+
48
+ def signature_base(params)
49
+ signature = []
50
+ signature << secret_key
51
+
52
+ params.keys.sort.each do |key|
53
+ next if key == "hash"
54
+ signature << params[key].to_s
55
+ end
56
+
57
+ signature.join(":")
58
+ end
59
+
60
+ end
61
+
62
+ end
63
+ end
@@ -0,0 +1,10 @@
1
+ <html>
2
+ <head>
3
+ </head>
4
+ <body>
5
+ <br/><br/><br/>
6
+ <a href="javascript: (function(){var script=document.createElement('script'); script.src='/__rack_bug__/bookmarklet.js'; document.getElementsByTagName('head')[0].appendChild(script);})()">
7
+ Toggle Rack::Bug
8
+ </a>
9
+ </body>
10
+ </html>
@@ -0,0 +1,217 @@
1
+ /**
2
+ *
3
+ * Secure Hash Algorithm (SHA1)
4
+ * http://www.webtoolkit.info/
5
+ *
6
+ **/
7
+
8
+ document.SHA1 = function(msg) {
9
+ function rotate_left(n,s) {
10
+ var t4 = ( n<<s ) | (n>>>(32-s));
11
+ return t4;
12
+ };
13
+
14
+ function lsb_hex(val) {
15
+ var str="";
16
+ var i;
17
+ var vh;
18
+ var vl;
19
+
20
+ for( i=0; i<=6; i+=2 ) {
21
+ vh = (val>>>(i*4+4))&0x0f;
22
+ vl = (val>>>(i*4))&0x0f;
23
+ str += vh.toString(16) + vl.toString(16);
24
+ }
25
+ return str;
26
+ };
27
+
28
+ function cvt_hex(val) {
29
+ var str="";
30
+ var i;
31
+ var v;
32
+
33
+ for( i=7; i>=0; i-- ) {
34
+ v = (val>>>(i*4))&0x0f;
35
+ str += v.toString(16);
36
+ }
37
+ return str;
38
+ };
39
+
40
+
41
+ function Utf8Encode(string) {
42
+ string = string.replace(/\r\n/g,"\n");
43
+ var utftext = "";
44
+
45
+ for (var n = 0; n < string.length; n++) {
46
+
47
+ var c = string.charCodeAt(n);
48
+
49
+ if (c < 128) {
50
+ utftext += String.fromCharCode(c);
51
+ }
52
+ else if((c > 127) && (c < 2048)) {
53
+ utftext += String.fromCharCode((c >> 6) | 192);
54
+ utftext += String.fromCharCode((c & 63) | 128);
55
+ }
56
+ else {
57
+ utftext += String.fromCharCode((c >> 12) | 224);
58
+ utftext += String.fromCharCode(((c >> 6) & 63) | 128);
59
+ utftext += String.fromCharCode((c & 63) | 128);
60
+ }
61
+
62
+ }
63
+
64
+ return utftext;
65
+ };
66
+
67
+ var blockstart;
68
+ var i, j;
69
+ var W = new Array(80);
70
+ var H0 = 0x67452301;
71
+ var H1 = 0xEFCDAB89;
72
+ var H2 = 0x98BADCFE;
73
+ var H3 = 0x10325476;
74
+ var H4 = 0xC3D2E1F0;
75
+ var A, B, C, D, E;
76
+ var temp;
77
+
78
+ msg = Utf8Encode(msg);
79
+
80
+ var msg_len = msg.length;
81
+
82
+ var word_array = new Array();
83
+ for( i=0; i<msg_len-3; i+=4 ) {
84
+ j = msg.charCodeAt(i)<<24 | msg.charCodeAt(i+1)<<16 |
85
+ msg.charCodeAt(i+2)<<8 | msg.charCodeAt(i+3);
86
+ word_array.push( j );
87
+ }
88
+
89
+ switch( msg_len % 4 ) {
90
+ case 0:
91
+ i = 0x080000000;
92
+ break;
93
+ case 1:
94
+ i = msg.charCodeAt(msg_len-1)<<24 | 0x0800000;
95
+ break;
96
+
97
+ case 2:
98
+ i = msg.charCodeAt(msg_len-2)<<24 | msg.charCodeAt(msg_len-1)<<16 | 0x08000;
99
+ break;
100
+
101
+ case 3:
102
+ i = msg.charCodeAt(msg_len-3)<<24 | msg.charCodeAt(msg_len-2)<<16 | msg.charCodeAt(msg_len-1)<<8 | 0x80;
103
+ break;
104
+ }
105
+
106
+ word_array.push( i );
107
+
108
+ while( (word_array.length % 16) != 14 ) word_array.push( 0 );
109
+
110
+ word_array.push( msg_len>>>29 );
111
+ word_array.push( (msg_len<<3)&0x0ffffffff );
112
+
113
+
114
+ for ( blockstart=0; blockstart<word_array.length; blockstart+=16 ) {
115
+
116
+ for( i=0; i<16; i++ ) W[i] = word_array[blockstart+i];
117
+ for( i=16; i<=79; i++ ) W[i] = rotate_left(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1);
118
+
119
+ A = H0;
120
+ B = H1;
121
+ C = H2;
122
+ D = H3;
123
+ E = H4;
124
+
125
+ for( i= 0; i<=19; i++ ) {
126
+ temp = (rotate_left(A,5) + ((B&C) | (~B&D)) + E + W[i] + 0x5A827999) & 0x0ffffffff;
127
+ E = D;
128
+ D = C;
129
+ C = rotate_left(B,30);
130
+ B = A;
131
+ A = temp;
132
+ }
133
+
134
+ for( i=20; i<=39; i++ ) {
135
+ temp = (rotate_left(A,5) + (B ^ C ^ D) + E + W[i] + 0x6ED9EBA1) & 0x0ffffffff;
136
+ E = D;
137
+ D = C;
138
+ C = rotate_left(B,30);
139
+ B = A;
140
+ A = temp;
141
+ }
142
+
143
+ for( i=40; i<=59; i++ ) {
144
+ temp = (rotate_left(A,5) + ((B&C) | (B&D) | (C&D)) + E + W[i] + 0x8F1BBCDC) & 0x0ffffffff;
145
+ E = D;
146
+ D = C;
147
+ C = rotate_left(B,30);
148
+ B = A;
149
+ A = temp;
150
+ }
151
+
152
+ for( i=60; i<=79; i++ ) {
153
+ temp = (rotate_left(A,5) + (B ^ C ^ D) + E + W[i] + 0xCA62C1D6) & 0x0ffffffff;
154
+ E = D;
155
+ D = C;
156
+ C = rotate_left(B,30);
157
+ B = A;
158
+ A = temp;
159
+ }
160
+
161
+ H0 = (H0 + A) & 0x0ffffffff;
162
+ H1 = (H1 + B) & 0x0ffffffff;
163
+ H2 = (H2 + C) & 0x0ffffffff;
164
+ H3 = (H3 + D) & 0x0ffffffff;
165
+ H4 = (H4 + E) & 0x0ffffffff;
166
+
167
+ }
168
+
169
+ var temp = cvt_hex(H0) + cvt_hex(H1) + cvt_hex(H2) + cvt_hex(H3) + cvt_hex(H4);
170
+
171
+ return temp.toLowerCase();
172
+ }
173
+
174
+ document.createCookie = function(name,value,days) {
175
+ if (days) {
176
+ var date = new Date();
177
+ date.setTime(date.getTime()+(days*24*60*60*1000));
178
+ var expires = "; expires="+date.toGMTString();
179
+ }
180
+ else
181
+ var expires = "";
182
+ document.cookie = name+"="+value+expires+"; path=/";
183
+ }
184
+
185
+ document.readCookie = function(name) {
186
+ var nameEQ = name + "=";
187
+ var ca = document.cookie.split(';');
188
+ for(var i=0;i < ca.length;i++) {
189
+ var c = ca[i];
190
+ while (c.charAt(0)==' ')
191
+ c = c.substring(1,c.length);
192
+ if (c.indexOf(nameEQ) == 0)
193
+ return c.substring(nameEQ.length,c.length);
194
+ }
195
+ return null;
196
+ }
197
+
198
+ document.eraseCookie = function(name) {
199
+ document.createCookie(name,"",-1);
200
+ }
201
+
202
+ document.rackBugBookmarklet = function() {
203
+ if (document.readCookie('rack_bug_password')) {
204
+ document.eraseCookie('rack_bug_password');
205
+ document.eraseCookie('rack_bug_enabled');
206
+ window.location.reload();
207
+ } else {
208
+ var password = prompt("Rack::Bug password:", "");
209
+ if (password != null) {
210
+ document.createCookie('rack_bug_password', document.SHA1('rack_bug:'+password));
211
+ document.createCookie('rack_bug_enabled', "1");
212
+ window.location.reload();
213
+ }
214
+ }
215
+ }
216
+
217
+ document.rackBugBookmarklet();
@@ -0,0 +1,216 @@
1
+ #rack_bug {
2
+ color: #000;
3
+ float: none;
4
+ margin: 0;
5
+ padding: 0;
6
+ position: static;
7
+ }
8
+
9
+ #rack_bug a {
10
+ color: #f7c757;
11
+ }
12
+ #rack_bug a:hover {
13
+ color: #aaa;
14
+ }
15
+
16
+ #rack_bug_toolbar {
17
+ background: #326342;
18
+ height: 30px;
19
+ z-index: 1000000000;
20
+ position:absolute;
21
+ left:0;
22
+ right:0;
23
+ cursor: pointer;
24
+ }
25
+ .rb_bottom #rack_bug_toolbar {
26
+ bottom:0;
27
+ border-top: 2px solid #234f32;
28
+ }
29
+ .rb_top #rack_bug_toolbar {
30
+ top:0;
31
+ border-bottom: 2px solid #234f32;
32
+ }
33
+
34
+ .rack_bug_error #rack_bug_toolbar {
35
+ background: #ff0000;
36
+ color: #fff;
37
+ border: none;
38
+ }
39
+
40
+ .rack_bug_error #rack_bug_toolbar p {
41
+ margin-top: 6px;
42
+ margin-left: 15px;
43
+ font-weight: bold;
44
+ color: #fff;
45
+ }
46
+
47
+ #rack_bug_toolbar ul {
48
+ margin: 0;
49
+ padding: 0;
50
+ list-style: none;
51
+ }
52
+
53
+ #rack_bug_toolbar li {
54
+ color: #fff;
55
+ display: inline;
56
+ font-size: 11px;
57
+ font-weight: bold;
58
+ float: none;
59
+ height: 20px;
60
+ margin: 0;
61
+ padding: 0;
62
+ line-height: 30px;
63
+ position: relative;
64
+ width: auto;
65
+ }
66
+ #rack_bug_toolbar li a {
67
+ border-left: 1px solid #487858;
68
+ padding: 8px 9px 9px;
69
+ }
70
+
71
+ #rack_bug_toolbar li a:hover {
72
+ background: #487858;
73
+ color: #fff;
74
+ }
75
+
76
+ #rack_bug_toolbar li:last-child {
77
+ border-right: 1px solid #487858;
78
+ }
79
+
80
+ #rack_bug_toolbar #rb_debug_button {
81
+ color: #92ef3f;
82
+ padding-left: 20px;
83
+ }
84
+
85
+ #rack_bug .panel_content {
86
+ background: #2a5738;
87
+ border-bottom: 2px solid #234f32;
88
+ border-top: 2px solid #487858;
89
+ display: none;
90
+ position: absolute;
91
+ margin: 0;
92
+ padding: 10px;
93
+ width: auto;
94
+ left: 0px;
95
+ right: 0px;
96
+ color: black;
97
+ z-index: 1000000;
98
+ overflow: auto;
99
+ }
100
+
101
+ #rack_bug.rb_top .panel_content {
102
+ top: 32px;
103
+ }
104
+
105
+ #rack_bug.rb_bottom .panel_content {
106
+ bottom: 32px;
107
+ }
108
+
109
+ #rack_bug .panel_content p a,
110
+ #rack_bug .panel_content dl a {
111
+ color: #40684c;
112
+ }
113
+
114
+ #rack_bug .panel_content p a:hover,
115
+ #rack_bug .panel_content dl a:hover {
116
+ color: #92EF3F;
117
+ }
118
+
119
+ #rack_bug .panel_content h3 {
120
+ border-bottom: 1px solid #40684c;
121
+ color: #92ef3f;
122
+ padding: 0 0 5px;
123
+ }
124
+
125
+ #rack_bug .panel_content p {
126
+ padding: 0 5px;
127
+ }
128
+
129
+ #rack_bug .panel_content p,
130
+ #rack_bug .panel_content table,
131
+ #rack_bug .panel_content ol,
132
+ #rack_bug .panel_content dl {
133
+ margin: 5px 0 15px;
134
+ background-color: #fff;
135
+ }
136
+
137
+ #rack_bug .panel_content ul {
138
+ padding: 10px 30px 10px 30px;
139
+ background-color: #fff;
140
+ }
141
+
142
+ #rack_bug .panel_content ul ul {
143
+ padding: 0;
144
+ }
145
+
146
+ #rack_bug .panel_content table {
147
+ width: 100%;
148
+ clear: both;
149
+ }
150
+
151
+ #rack_bug .panel_content table a {
152
+ color: #40684C;
153
+ }
154
+
155
+ #rack_bug .panel_content table th {
156
+ background-color: #9dcc49;
157
+ font-weight: bold;
158
+ color: #000;
159
+ font-size: 11px;
160
+ padding: 3px 7px 3px;
161
+ text-align: left;
162
+ cursor: pointer;
163
+ border-right: 1px solid #b9d977;
164
+ }
165
+
166
+ #rack_bug .panel_content table td {
167
+ padding: 5px 10px;
168
+ font-size: 11px;
169
+ background: #fff;
170
+ color: #000;
171
+ vertical-align: top;
172
+ }
173
+ #rack_bug .panel_content table tr.odd td {
174
+ background: #eee;
175
+ }
176
+
177
+ #rack_bug .panel_content .rack_bug_close {
178
+ float: right;
179
+ font-weight: bold;
180
+ }
181
+
182
+ #rack_bug .panel_content dt, #rack_bug .panel_content dd {
183
+ display: block;
184
+ }
185
+
186
+ #rack_bug .panel_content dd {
187
+ margin-left: 10px;
188
+ }
189
+
190
+ #rack_bug .panel_content table tr.odd td.rack_bug_spinner,
191
+ #rack_bug .panel_content table tr.even td.rack_bug_spinner,
192
+ #rack_bug .panel_content table td.rack_bug_spinner,
193
+ #rack_bug .rack_bug_spinner {
194
+ background-image: url(/__rack_bug__/spinner.gif);
195
+ background-repeat: no-repeat;
196
+ background-position: center center;
197
+ text-indent: -3000px;
198
+ color: transparent;
199
+ }
200
+
201
+ #rack_bug #sql.panel_content th.time {
202
+ width: 80px;
203
+ }
204
+
205
+ #rack_bug #sql.panel_content th.backtrace {
206
+ width: 100px;
207
+ }
208
+
209
+ #rack_bug #sql.panel_content th.actions {
210
+ width: 150px;
211
+ }
212
+ #rack_bug #request_variables td.code > div {
213
+ max-height:200px;
214
+ max-width: 800px;
215
+ overflow:auto;
216
+ }