nano-sharp-hub 0.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 (57) hide show
  1. checksums.yaml +7 -0
  2. data/nano-sharp-hub.gemspec +12 -0
  3. data/rack-3.2.6/CHANGELOG.md +1346 -0
  4. data/rack-3.2.6/CONTRIBUTING.md +144 -0
  5. data/rack-3.2.6/MIT-LICENSE +20 -0
  6. data/rack-3.2.6/README.md +384 -0
  7. data/rack-3.2.6/SPEC.rdoc +258 -0
  8. data/rack-3.2.6/lib/rack/auth/abstract/handler.rb +41 -0
  9. data/rack-3.2.6/lib/rack/auth/abstract/request.rb +51 -0
  10. data/rack-3.2.6/lib/rack/auth/basic.rb +58 -0
  11. data/rack-3.2.6/lib/rack/bad_request.rb +8 -0
  12. data/rack-3.2.6/lib/rack/body_proxy.rb +63 -0
  13. data/rack-3.2.6/lib/rack/builder.rb +296 -0
  14. data/rack-3.2.6/lib/rack/cascade.rb +67 -0
  15. data/rack-3.2.6/lib/rack/common_logger.rb +89 -0
  16. data/rack-3.2.6/lib/rack/conditional_get.rb +87 -0
  17. data/rack-3.2.6/lib/rack/config.rb +22 -0
  18. data/rack-3.2.6/lib/rack/constants.rb +68 -0
  19. data/rack-3.2.6/lib/rack/content_length.rb +34 -0
  20. data/rack-3.2.6/lib/rack/content_type.rb +33 -0
  21. data/rack-3.2.6/lib/rack/deflater.rb +158 -0
  22. data/rack-3.2.6/lib/rack/directory.rb +208 -0
  23. data/rack-3.2.6/lib/rack/etag.rb +71 -0
  24. data/rack-3.2.6/lib/rack/events.rb +172 -0
  25. data/rack-3.2.6/lib/rack/files.rb +216 -0
  26. data/rack-3.2.6/lib/rack/head.rb +25 -0
  27. data/rack-3.2.6/lib/rack/headers.rb +238 -0
  28. data/rack-3.2.6/lib/rack/lint.rb +964 -0
  29. data/rack-3.2.6/lib/rack/lock.rb +29 -0
  30. data/rack-3.2.6/lib/rack/media_type.rb +52 -0
  31. data/rack-3.2.6/lib/rack/method_override.rb +56 -0
  32. data/rack-3.2.6/lib/rack/mime.rb +694 -0
  33. data/rack-3.2.6/lib/rack/mock.rb +3 -0
  34. data/rack-3.2.6/lib/rack/mock_request.rb +161 -0
  35. data/rack-3.2.6/lib/rack/mock_response.rb +156 -0
  36. data/rack-3.2.6/lib/rack/multipart/generator.rb +99 -0
  37. data/rack-3.2.6/lib/rack/multipart/parser.rb +621 -0
  38. data/rack-3.2.6/lib/rack/multipart/uploaded_file.rb +82 -0
  39. data/rack-3.2.6/lib/rack/multipart.rb +77 -0
  40. data/rack-3.2.6/lib/rack/null_logger.rb +48 -0
  41. data/rack-3.2.6/lib/rack/query_parser.rb +261 -0
  42. data/rack-3.2.6/lib/rack/recursive.rb +66 -0
  43. data/rack-3.2.6/lib/rack/reloader.rb +112 -0
  44. data/rack-3.2.6/lib/rack/request.rb +790 -0
  45. data/rack-3.2.6/lib/rack/response.rb +403 -0
  46. data/rack-3.2.6/lib/rack/rewindable_input.rb +116 -0
  47. data/rack-3.2.6/lib/rack/runtime.rb +35 -0
  48. data/rack-3.2.6/lib/rack/sendfile.rb +197 -0
  49. data/rack-3.2.6/lib/rack/show_exceptions.rb +409 -0
  50. data/rack-3.2.6/lib/rack/show_status.rb +121 -0
  51. data/rack-3.2.6/lib/rack/static.rb +192 -0
  52. data/rack-3.2.6/lib/rack/tempfile_reaper.rb +33 -0
  53. data/rack-3.2.6/lib/rack/urlmap.rb +99 -0
  54. data/rack-3.2.6/lib/rack/utils.rb +714 -0
  55. data/rack-3.2.6/lib/rack/version.rb +17 -0
  56. data/rack-3.2.6/lib/rack.rb +64 -0
  57. metadata +96 -0
@@ -0,0 +1,197 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'constants'
4
+ require_relative 'utils'
5
+ require_relative 'body_proxy'
6
+
7
+ module Rack
8
+
9
+ # = Sendfile
10
+ #
11
+ # The Sendfile middleware intercepts responses whose body is being
12
+ # served from a file and replaces it with a server specific x-sendfile
13
+ # header. The web server is then responsible for writing the file contents
14
+ # to the client. This can dramatically reduce the amount of work required
15
+ # by the Ruby backend and takes advantage of the web server's optimized file
16
+ # delivery code.
17
+ #
18
+ # In order to take advantage of this middleware, the response body must
19
+ # respond to +to_path+ and the request must include an `x-sendfile-type`
20
+ # header. Rack::Files and other components implement +to_path+ so there's
21
+ # rarely anything you need to do in your application. The `x-sendfile-type`
22
+ # header is typically set in your web servers configuration. The following
23
+ # sections attempt to document
24
+ #
25
+ # === Nginx
26
+ #
27
+ # Nginx supports the `x-accel-redirect` header. This is similar to `x-sendfile`
28
+ # but requires parts of the filesystem to be mapped into a private URL
29
+ # hierarchy.
30
+ #
31
+ # The following example shows the Nginx configuration required to create
32
+ # a private "/files/" area, enable `x-accel-redirect`, and pass the special
33
+ # `x-accel-mapping` header to the backend:
34
+ #
35
+ # location ~ /files/(.*) {
36
+ # internal;
37
+ # alias /var/www/$1;
38
+ # }
39
+ #
40
+ # location / {
41
+ # proxy_redirect off;
42
+ #
43
+ # proxy_set_header Host $host;
44
+ # proxy_set_header X-Real-IP $remote_addr;
45
+ # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
46
+ #
47
+ # proxy_set_header x-accel-mapping /var/www/=/files/;
48
+ #
49
+ # proxy_pass http://127.0.0.1:8080/;
50
+ # }
51
+ #
52
+ # The `x-accel-mapping` header should specify the location on the file system,
53
+ # followed by an equals sign (=), followed name of the private URL pattern
54
+ # that it maps to. The middleware performs a case-insensitive substitution on the
55
+ # resulting path.
56
+ #
57
+ # To enable `x-accel-redirect`, you must configure the middleware explicitly:
58
+ #
59
+ # use Rack::Sendfile, "x-accel-redirect"
60
+ #
61
+ # For security reasons, the `x-sendfile-type` header from requests is ignored.
62
+ # The sendfile variation must be set via the middleware constructor.
63
+ #
64
+ # See Also: https://www.nginx.com/resources/wiki/start/topics/examples/xsendfile
65
+ #
66
+ # === lighttpd
67
+ #
68
+ # Lighttpd has supported some variation of the `x-sendfile` header for some
69
+ # time, although only recent version support `x-sendfile` in a reverse proxy
70
+ # configuration.
71
+ #
72
+ # $HTTP["host"] == "example.com" {
73
+ # proxy-core.protocol = "http"
74
+ # proxy-core.balancer = "round-robin"
75
+ # proxy-core.backends = (
76
+ # "127.0.0.1:8000",
77
+ # "127.0.0.1:8001",
78
+ # ...
79
+ # )
80
+ #
81
+ # proxy-core.allow-x-sendfile = "enable"
82
+ # proxy-core.rewrite-request = (
83
+ # "x-sendfile-type" => (".*" => "x-sendfile")
84
+ # )
85
+ # }
86
+ #
87
+ # See Also: http://redmine.lighttpd.net/wiki/lighttpd/Docs:ModProxyCore
88
+ #
89
+ # === Apache
90
+ #
91
+ # `x-sendfile` is supported under Apache 2.x using a separate module:
92
+ #
93
+ # https://tn123.org/mod_xsendfile/
94
+ #
95
+ # Once the module is compiled and installed, you can enable it using
96
+ # XSendFile config directive:
97
+ #
98
+ # RequestHeader Set x-sendfile-type x-sendfile
99
+ # ProxyPassReverse / http://localhost:8001/
100
+ # XSendFile on
101
+ #
102
+ # === Mapping parameter
103
+ #
104
+ # The third parameter allows for an overriding extension of the
105
+ # `x-accel-mapping` header. Mappings should be provided in tuples of internal to
106
+ # external. The internal values may contain regular expression syntax, they
107
+ # will be matched with case indifference.
108
+ #
109
+ # When `x-accel-redirect` is explicitly enabled via the variation parameter,
110
+ # and no application-level mappings are provided, the middleware will read
111
+ # the `x-accel-mapping` header from the proxy. This allows nginx to control
112
+ # the path mapping without requiring application-level configuration.
113
+ #
114
+ # === Security
115
+ #
116
+ # For security reasons, the `x-sendfile-type` header from HTTP requests is
117
+ # ignored. The sendfile variation must be explicitly configured via the
118
+ # middleware constructor to prevent information disclosure vulnerabilities
119
+ # where attackers could bypass proxy restrictions.
120
+
121
+ class Sendfile
122
+ def initialize(app, variation = nil, mappings = [])
123
+ @app = app
124
+ @variation = variation
125
+ @mappings = mappings.map do |internal, external|
126
+ [/\A#{internal}/i, external]
127
+ end
128
+ end
129
+
130
+ def call(env)
131
+ _, headers, body = response = @app.call(env)
132
+
133
+ if body.respond_to?(:to_path)
134
+ case type = variation(env)
135
+ when /x-accel-redirect/i
136
+ path = ::File.expand_path(body.to_path)
137
+ if url = map_accel_path(env, path)
138
+ headers[CONTENT_LENGTH] = '0'
139
+ # '?' must be percent-encoded because it is not query string but a part of path
140
+ headers[type.downcase] = ::Rack::Utils.escape_path(url).gsub('?', '%3F')
141
+ obody = body
142
+ response[2] = Rack::BodyProxy.new([]) do
143
+ obody.close if obody.respond_to?(:close)
144
+ end
145
+ else
146
+ env[RACK_ERRORS].puts "x-accel-mapping header missing"
147
+ end
148
+ when /x-sendfile|x-lighttpd-send-file/i
149
+ path = ::File.expand_path(body.to_path)
150
+ headers[CONTENT_LENGTH] = '0'
151
+ headers[type.downcase] = path
152
+ obody = body
153
+ response[2] = Rack::BodyProxy.new([]) do
154
+ obody.close if obody.respond_to?(:close)
155
+ end
156
+ when '', nil
157
+ else
158
+ env[RACK_ERRORS].puts "Unknown x-sendfile variation: #{type.inspect}"
159
+ end
160
+ end
161
+ response
162
+ end
163
+
164
+ private
165
+
166
+ def variation(env)
167
+ # Note: HTTP_X_SENDFILE_TYPE is intentionally NOT read for security reasons.
168
+ # Attackers could use this header to enable x-accel-redirect and bypass proxy restrictions.
169
+ @variation || env['sendfile.type']
170
+ end
171
+
172
+ def x_accel_mapping(env)
173
+ # Only allow header when:
174
+ # 1. `x-accel-redirect` is explicitly enabled via constructor.
175
+ # 2. No application-level mappings are configured.
176
+ return nil unless @variation =~ /x-accel-redirect/i
177
+ return nil if @mappings.any?
178
+
179
+ env['HTTP_X_ACCEL_MAPPING']
180
+ end
181
+
182
+ def map_accel_path(env, path)
183
+ if mapping = @mappings.find { |internal, _| internal =~ path }
184
+ return path.sub(*mapping)
185
+ elsif mapping = x_accel_mapping(env)
186
+ # Safe to use header: explicit config + no app mappings:
187
+ mapping.split(',').map(&:strip).each do |m|
188
+ internal, external = m.split('=', 2).map(&:strip)
189
+ new_path = path.sub(/\A#{Regexp.escape(internal)}/i, external)
190
+ return new_path unless path == new_path
191
+ end
192
+
193
+ return path
194
+ end
195
+ end
196
+ end
197
+ end
@@ -0,0 +1,409 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'erb'
4
+
5
+ require_relative 'constants'
6
+ require_relative 'utils'
7
+ require_relative 'request'
8
+
9
+ module Rack
10
+ # Rack::ShowExceptions catches all exceptions raised from the app it
11
+ # wraps. It shows a useful backtrace with the sourcefile and
12
+ # clickable context, the whole Rack environment and the request
13
+ # data.
14
+ #
15
+ # Be careful when you use this on public-facing sites as it could
16
+ # reveal information helpful to attackers.
17
+
18
+ class ShowExceptions
19
+ CONTEXT = 7
20
+
21
+ Frame = Struct.new(:filename, :lineno, :function,
22
+ :pre_context_lineno, :pre_context,
23
+ :context_line, :post_context_lineno,
24
+ :post_context)
25
+
26
+ def initialize(app)
27
+ @app = app
28
+ end
29
+
30
+ def call(env)
31
+ @app.call(env)
32
+ rescue StandardError, LoadError, SyntaxError => e
33
+ exception_string = dump_exception(e)
34
+
35
+ env[RACK_ERRORS].puts(exception_string)
36
+ env[RACK_ERRORS].flush
37
+
38
+ if accepts_html?(env)
39
+ content_type = "text/html"
40
+ body = pretty(env, e)
41
+ else
42
+ content_type = "text/plain"
43
+ body = exception_string
44
+ end
45
+
46
+ [
47
+ 500,
48
+ {
49
+ CONTENT_TYPE => content_type,
50
+ CONTENT_LENGTH => body.bytesize.to_s,
51
+ },
52
+ [body],
53
+ ]
54
+ end
55
+
56
+ def prefers_plaintext?(env)
57
+ !accepts_html?(env)
58
+ end
59
+
60
+ def accepts_html?(env)
61
+ Rack::Utils.best_q_match(env["HTTP_ACCEPT"], %w[text/html])
62
+ end
63
+ private :accepts_html?
64
+
65
+ def dump_exception(exception)
66
+ if exception.respond_to?(:detailed_message)
67
+ message = exception.detailed_message(highlight: false)
68
+ # :nocov:
69
+ # Ruby 3.2 added Exception#detailed_message, so the else
70
+ # branch cannot be hit on the current Ruby version.
71
+ else
72
+ message = exception.message
73
+ # :nocov:
74
+ end
75
+ string = "#{exception.class}: #{message}\n".dup
76
+ string << exception.backtrace.map { |l| "\t#{l}" }.join("\n")
77
+ string
78
+ end
79
+
80
+ def pretty(env, exception)
81
+ req = Rack::Request.new(env)
82
+
83
+ # This double assignment is to prevent an "unused variable" warning.
84
+ # Yes, it is dumb, but I don't like Ruby yelling at me.
85
+ path = path = (req.script_name + req.path_info).squeeze("/")
86
+
87
+ # This double assignment is to prevent an "unused variable" warning.
88
+ # Yes, it is dumb, but I don't like Ruby yelling at me.
89
+ frames = frames = exception.backtrace.map { |line|
90
+ frame = Frame.new
91
+ if line =~ /(.*?):(\d+)(:in `(.*)')?/
92
+ frame.filename = $1
93
+ frame.lineno = $2.to_i
94
+ frame.function = $4
95
+
96
+ begin
97
+ lineno = frame.lineno - 1
98
+ lines = ::File.readlines(frame.filename)
99
+ frame.pre_context_lineno = [lineno - CONTEXT, 0].max
100
+ frame.pre_context = lines[frame.pre_context_lineno...lineno]
101
+ frame.context_line = lines[lineno].chomp
102
+ frame.post_context_lineno = [lineno + CONTEXT, lines.size].min
103
+ frame.post_context = lines[lineno + 1..frame.post_context_lineno]
104
+ rescue
105
+ end
106
+
107
+ frame
108
+ else
109
+ nil
110
+ end
111
+ }.compact
112
+
113
+ template.result(binding)
114
+ end
115
+
116
+ def template
117
+ TEMPLATE
118
+ end
119
+
120
+ def h(obj) # :nodoc:
121
+ case obj
122
+ when String
123
+ Utils.escape_html(obj)
124
+ else
125
+ Utils.escape_html(obj.inspect)
126
+ end
127
+ end
128
+
129
+ # :stopdoc:
130
+
131
+ # adapted from Django <www.djangoproject.com>
132
+ # Copyright (c) Django Software Foundation and individual contributors.
133
+ # Used under the modified BSD license:
134
+ # http://www.xfree86.org/3.3.6/COPYRIGHT2.html#5
135
+ TEMPLATE = ERB.new(<<-'HTML'.gsub(/^ /, ''))
136
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
137
+ <html lang="en">
138
+ <head>
139
+ <meta http-equiv="content-type" content="text/html; charset=utf-8" />
140
+ <meta name="robots" content="NONE,NOARCHIVE" />
141
+ <title><%=h exception.class %> at <%=h path %></title>
142
+ <style type="text/css">
143
+ html * { padding:0; margin:0; }
144
+ body * { padding:10px 20px; }
145
+ body * * { padding:0; }
146
+ body { font:small sans-serif; }
147
+ body>div { border-bottom:1px solid #ddd; }
148
+ h1 { font-weight:normal; }
149
+ h2 { margin-bottom:.8em; }
150
+ h2 span { font-size:80%; color:#666; font-weight:normal; }
151
+ h3 { margin:1em 0 .5em 0; }
152
+ h4 { margin:0 0 .5em 0; font-weight: normal; }
153
+ table {
154
+ border:1px solid #ccc; border-collapse: collapse; background:white; }
155
+ tbody td, tbody th { vertical-align:top; padding:2px 3px; }
156
+ thead th {
157
+ padding:1px 6px 1px 3px; background:#fefefe; text-align:left;
158
+ font-weight:normal; font-size:11px; border:1px solid #ddd; }
159
+ tbody th { text-align:right; color:#666; padding-right:.5em; }
160
+ table.vars { margin:5px 0 2px 40px; }
161
+ table.vars td, table.req td { font-family:monospace; }
162
+ table td.code { width:100%;}
163
+ table td.code div { overflow:hidden; }
164
+ table.source th { color:#666; }
165
+ table.source td {
166
+ font-family:monospace; white-space:pre; border-bottom:1px solid #eee; }
167
+ ul.traceback { list-style-type:none; }
168
+ ul.traceback li.frame { margin-bottom:1em; }
169
+ div.context { margin: 10px 0; }
170
+ div.context ol {
171
+ padding-left:30px; margin:0 10px; list-style-position: inside; }
172
+ div.context ol li {
173
+ font-family:monospace; white-space:pre; color:#666; cursor:pointer; }
174
+ div.context ol.context-line li { color:black; background-color:#ccc; }
175
+ div.context ol.context-line li span { float: right; }
176
+ div.commands { margin-left: 40px; }
177
+ div.commands a { color:black; text-decoration:none; }
178
+ #summary { background: #ffc; }
179
+ #summary h2 { font-family: monospace; font-weight: normal; color: #666; white-space: pre-wrap; }
180
+ #summary ul#quicklinks { list-style-type: none; margin-bottom: 2em; }
181
+ #summary ul#quicklinks li { float: left; padding: 0 1em; }
182
+ #summary ul#quicklinks>li+li { border-left: 1px #666 solid; }
183
+ #explanation { background:#eee; }
184
+ #template, #template-not-exist { background:#f6f6f6; }
185
+ #template-not-exist ul { margin: 0 0 0 20px; }
186
+ #traceback { background:#eee; }
187
+ #requestinfo { background:#f6f6f6; padding-left:120px; }
188
+ #summary table { border:none; background:transparent; }
189
+ #requestinfo h2, #requestinfo h3 { position:relative; margin-left:-100px; }
190
+ #requestinfo h3 { margin-bottom:-1em; }
191
+ .error { background: #ffc; }
192
+ .specific { color:#cc3300; font-weight:bold; }
193
+ </style>
194
+ <script type="text/javascript">
195
+ //<!--
196
+ function getElementsByClassName(oElm, strTagName, strClassName){
197
+ // Written by Jonathan Snook, http://www.snook.ca/jon;
198
+ // Add-ons by Robert Nyman, http://www.robertnyman.com
199
+ var arrElements = (strTagName == "*" && document.all)? document.all :
200
+ oElm.getElementsByTagName(strTagName);
201
+ var arrReturnElements = new Array();
202
+ strClassName = strClassName.replace(/\-/g, "\\-");
203
+ var oRegExp = new RegExp("(^|\\s)" + strClassName + "(\\s|$$)");
204
+ var oElement;
205
+ for(var i=0; i<arrElements.length; i++){
206
+ oElement = arrElements[i];
207
+ if(oRegExp.test(oElement.className)){
208
+ arrReturnElements.push(oElement);
209
+ }
210
+ }
211
+ return (arrReturnElements)
212
+ }
213
+ function hideAll(elems) {
214
+ for (var e = 0; e < elems.length; e++) {
215
+ elems[e].style.display = 'none';
216
+ }
217
+ }
218
+ window.onload = function() {
219
+ hideAll(getElementsByClassName(document, 'table', 'vars'));
220
+ hideAll(getElementsByClassName(document, 'ol', 'pre-context'));
221
+ hideAll(getElementsByClassName(document, 'ol', 'post-context'));
222
+ }
223
+ function toggle() {
224
+ for (var i = 0; i < arguments.length; i++) {
225
+ var e = document.getElementById(arguments[i]);
226
+ if (e) {
227
+ e.style.display = e.style.display == 'none' ? 'block' : 'none';
228
+ }
229
+ }
230
+ return false;
231
+ }
232
+ function varToggle(link, id) {
233
+ toggle('v' + id);
234
+ var s = link.getElementsByTagName('span')[0];
235
+ var uarr = String.fromCharCode(0x25b6);
236
+ var darr = String.fromCharCode(0x25bc);
237
+ s.innerHTML = s.innerHTML == uarr ? darr : uarr;
238
+ return false;
239
+ }
240
+ //-->
241
+ </script>
242
+ </head>
243
+ <body>
244
+
245
+ <div id="summary">
246
+ <h1><%=h exception.class %> at <%=h path %></h1>
247
+ <% if exception.respond_to?(:detailed_message) %>
248
+ <h2><%=h exception.detailed_message(highlight: false) %></h2>
249
+ <% else %>
250
+ <h2><%=h exception.message %></h2>
251
+ <% end %>
252
+ <table><tr>
253
+ <th>Ruby</th>
254
+ <td>
255
+ <% if first = frames.first %>
256
+ <code><%=h first.filename %></code>: in <code><%=h first.function %></code>, line <%=h frames.first.lineno %>
257
+ <% else %>
258
+ unknown location
259
+ <% end %>
260
+ </td>
261
+ </tr><tr>
262
+ <th>Web</th>
263
+ <td><code><%=h req.request_method %> <%=h(req.host + path)%></code></td>
264
+ </tr></table>
265
+
266
+ <h3>Jump to:</h3>
267
+ <ul id="quicklinks">
268
+ <li><a href="#get-info">GET</a></li>
269
+ <li><a href="#post-info">POST</a></li>
270
+ <li><a href="#cookie-info">Cookies</a></li>
271
+ <li><a href="#env-info">ENV</a></li>
272
+ </ul>
273
+ </div>
274
+
275
+ <div id="traceback">
276
+ <h2>Traceback <span>(innermost first)</span></h2>
277
+ <ul class="traceback">
278
+ <% frames.each { |frame| %>
279
+ <li class="frame">
280
+ <code><%=h frame.filename %></code>: in <code><%=h frame.function %></code>
281
+
282
+ <% if frame.context_line %>
283
+ <div class="context" id="c<%=h frame.object_id %>">
284
+ <% if frame.pre_context %>
285
+ <ol start="<%=h frame.pre_context_lineno+1 %>" class="pre-context" id="pre<%=h frame.object_id %>">
286
+ <% frame.pre_context.each { |line| %>
287
+ <li onclick="toggle('pre<%=h frame.object_id %>', 'post<%=h frame.object_id %>')"><%=h line %></li>
288
+ <% } %>
289
+ </ol>
290
+ <% end %>
291
+
292
+ <ol start="<%=h frame.lineno %>" class="context-line">
293
+ <li onclick="toggle('pre<%=h frame.object_id %>', 'post<%=h frame.object_id %>')"><%=h frame.context_line %><span>...</span></li></ol>
294
+
295
+ <% if frame.post_context %>
296
+ <ol start='<%=h frame.lineno+1 %>' class="post-context" id="post<%=h frame.object_id %>">
297
+ <% frame.post_context.each { |line| %>
298
+ <li onclick="toggle('pre<%=h frame.object_id %>', 'post<%=h frame.object_id %>')"><%=h line %></li>
299
+ <% } %>
300
+ </ol>
301
+ <% end %>
302
+ </div>
303
+ <% end %>
304
+ </li>
305
+ <% } %>
306
+ </ul>
307
+ </div>
308
+
309
+ <div id="requestinfo">
310
+ <h2>Request information</h2>
311
+
312
+ <h3 id="get-info">GET</h3>
313
+ <% if req.GET and not req.GET.empty? %>
314
+ <table class="req">
315
+ <thead>
316
+ <tr>
317
+ <th>Variable</th>
318
+ <th>Value</th>
319
+ </tr>
320
+ </thead>
321
+ <tbody>
322
+ <% req.GET.sort_by { |k, v| k.to_s }.each { |key, val| %>
323
+ <tr>
324
+ <td><%=h key %></td>
325
+ <td class="code"><div><%=h val.inspect %></div></td>
326
+ </tr>
327
+ <% } %>
328
+ </tbody>
329
+ </table>
330
+ <% else %>
331
+ <p>No GET data.</p>
332
+ <% end %>
333
+
334
+ <h3 id="post-info">POST</h3>
335
+ <% if ((req.POST and not req.POST.empty?) rescue (no_post_data = "Invalid POST data"; nil)) %>
336
+ <table class="req">
337
+ <thead>
338
+ <tr>
339
+ <th>Variable</th>
340
+ <th>Value</th>
341
+ </tr>
342
+ </thead>
343
+ <tbody>
344
+ <% req.POST.sort_by { |k, v| k.to_s }.each { |key, val| %>
345
+ <tr>
346
+ <td><%=h key %></td>
347
+ <td class="code"><div><%=h val.inspect %></div></td>
348
+ </tr>
349
+ <% } %>
350
+ </tbody>
351
+ </table>
352
+ <% else %>
353
+ <p><%= no_post_data || "No POST data" %>.</p>
354
+ <% end %>
355
+
356
+
357
+ <h3 id="cookie-info">COOKIES</h3>
358
+ <% unless req.cookies.empty? %>
359
+ <table class="req">
360
+ <thead>
361
+ <tr>
362
+ <th>Variable</th>
363
+ <th>Value</th>
364
+ </tr>
365
+ </thead>
366
+ <tbody>
367
+ <% req.cookies.each { |key, val| %>
368
+ <tr>
369
+ <td><%=h key %></td>
370
+ <td class="code"><div><%=h val.inspect %></div></td>
371
+ </tr>
372
+ <% } %>
373
+ </tbody>
374
+ </table>
375
+ <% else %>
376
+ <p>No cookie data.</p>
377
+ <% end %>
378
+
379
+ <h3 id="env-info">Rack ENV</h3>
380
+ <table class="req">
381
+ <thead>
382
+ <tr>
383
+ <th>Variable</th>
384
+ <th>Value</th>
385
+ </tr>
386
+ </thead>
387
+ <tbody>
388
+ <% env.sort_by { |k, v| k.to_s }.each { |key, val| %>
389
+ <tr>
390
+ <td><%=h key %></td>
391
+ <td class="code"><div><%=h val.inspect %></div></td>
392
+ </tr>
393
+ <% } %>
394
+ </tbody>
395
+ </table>
396
+
397
+ </div>
398
+
399
+ <div id="explanation">
400
+ <p>
401
+ You're seeing this error because you use <code>Rack::ShowExceptions</code>.
402
+ </p>
403
+ </div>
404
+
405
+ </body>
406
+ </html>
407
+ HTML
408
+ end
409
+ end