rack 1.4.7 → 2.1.4

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 (183) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +77 -0
  3. data/{COPYING → MIT-LICENSE} +4 -2
  4. data/README.rdoc +122 -456
  5. data/Rakefile +32 -31
  6. data/SPEC +119 -29
  7. data/bin/rackup +1 -0
  8. data/contrib/rack_logo.svg +164 -111
  9. data/example/lobster.ru +2 -0
  10. data/example/protectedlobster.rb +4 -2
  11. data/example/protectedlobster.ru +3 -1
  12. data/lib/rack/auth/abstract/handler.rb +7 -5
  13. data/lib/rack/auth/abstract/request.rb +8 -6
  14. data/lib/rack/auth/basic.rb +5 -2
  15. data/lib/rack/auth/digest/md5.rb +10 -8
  16. data/lib/rack/auth/digest/nonce.rb +6 -3
  17. data/lib/rack/auth/digest/params.rb +5 -4
  18. data/lib/rack/auth/digest/request.rb +4 -2
  19. data/lib/rack/body_proxy.rb +11 -9
  20. data/lib/rack/builder.rb +63 -20
  21. data/lib/rack/cascade.rb +10 -9
  22. data/lib/rack/chunked.rb +45 -11
  23. data/lib/rack/{commonlogger.rb → common_logger.rb} +24 -15
  24. data/lib/rack/{conditionalget.rb → conditional_get.rb} +20 -6
  25. data/lib/rack/config.rb +7 -0
  26. data/lib/rack/content_length.rb +12 -6
  27. data/lib/rack/content_type.rb +4 -2
  28. data/lib/rack/core_ext/regexp.rb +14 -0
  29. data/lib/rack/deflater.rb +73 -42
  30. data/lib/rack/directory.rb +77 -56
  31. data/lib/rack/etag.rb +25 -13
  32. data/lib/rack/events.rb +156 -0
  33. data/lib/rack/file.rb +4 -143
  34. data/lib/rack/files.rb +178 -0
  35. data/lib/rack/handler/cgi.rb +18 -17
  36. data/lib/rack/handler/fastcgi.rb +21 -17
  37. data/lib/rack/handler/lsws.rb +14 -12
  38. data/lib/rack/handler/scgi.rb +27 -21
  39. data/lib/rack/handler/thin.rb +19 -5
  40. data/lib/rack/handler/webrick.rb +66 -24
  41. data/lib/rack/handler.rb +29 -19
  42. data/lib/rack/head.rb +21 -14
  43. data/lib/rack/lint.rb +259 -65
  44. data/lib/rack/lobster.rb +17 -10
  45. data/lib/rack/lock.rb +19 -10
  46. data/lib/rack/logger.rb +4 -2
  47. data/lib/rack/media_type.rb +43 -0
  48. data/lib/rack/method_override.rb +52 -0
  49. data/lib/rack/mime.rb +43 -6
  50. data/lib/rack/mock.rb +109 -44
  51. data/lib/rack/multipart/generator.rb +11 -12
  52. data/lib/rack/multipart/parser.rb +302 -115
  53. data/lib/rack/multipart/uploaded_file.rb +4 -3
  54. data/lib/rack/multipart.rb +40 -9
  55. data/lib/rack/null_logger.rb +39 -0
  56. data/lib/rack/query_parser.rb +218 -0
  57. data/lib/rack/recursive.rb +14 -11
  58. data/lib/rack/reloader.rb +12 -5
  59. data/lib/rack/request.rb +484 -270
  60. data/lib/rack/response.rb +196 -77
  61. data/lib/rack/rewindable_input.rb +5 -14
  62. data/lib/rack/runtime.rb +13 -6
  63. data/lib/rack/sendfile.rb +44 -20
  64. data/lib/rack/server.rb +175 -61
  65. data/lib/rack/session/abstract/id.rb +276 -133
  66. data/lib/rack/session/cookie.rb +75 -40
  67. data/lib/rack/session/memcache.rb +4 -87
  68. data/lib/rack/session/pool.rb +24 -18
  69. data/lib/rack/show_exceptions.rb +392 -0
  70. data/lib/rack/{showstatus.rb → show_status.rb} +11 -9
  71. data/lib/rack/static.rb +65 -38
  72. data/lib/rack/tempfile_reaper.rb +24 -0
  73. data/lib/rack/urlmap.rb +40 -15
  74. data/lib/rack/utils.rb +316 -285
  75. data/lib/rack.rb +78 -23
  76. data/rack.gemspec +26 -19
  77. metadata +44 -209
  78. data/KNOWN-ISSUES +0 -30
  79. data/lib/rack/backports/uri/common_18.rb +0 -56
  80. data/lib/rack/backports/uri/common_192.rb +0 -52
  81. data/lib/rack/backports/uri/common_193.rb +0 -29
  82. data/lib/rack/handler/evented_mongrel.rb +0 -8
  83. data/lib/rack/handler/mongrel.rb +0 -100
  84. data/lib/rack/handler/swiftiplied_mongrel.rb +0 -8
  85. data/lib/rack/methodoverride.rb +0 -33
  86. data/lib/rack/nulllogger.rb +0 -18
  87. data/lib/rack/showexceptions.rb +0 -378
  88. data/test/builder/anything.rb +0 -5
  89. data/test/builder/comment.ru +0 -4
  90. data/test/builder/end.ru +0 -5
  91. data/test/builder/line.ru +0 -1
  92. data/test/builder/options.ru +0 -2
  93. data/test/cgi/assets/folder/test.js +0 -1
  94. data/test/cgi/assets/fonts/font.eot +0 -1
  95. data/test/cgi/assets/images/image.png +0 -1
  96. data/test/cgi/assets/index.html +0 -1
  97. data/test/cgi/assets/javascripts/app.js +0 -1
  98. data/test/cgi/assets/stylesheets/app.css +0 -1
  99. data/test/cgi/lighttpd.conf +0 -26
  100. data/test/cgi/lighttpd.errors +0 -1
  101. data/test/cgi/rackup_stub.rb +0 -6
  102. data/test/cgi/sample_rackup.ru +0 -5
  103. data/test/cgi/test +0 -9
  104. data/test/cgi/test+directory/test+file +0 -1
  105. data/test/cgi/test.fcgi +0 -8
  106. data/test/cgi/test.ru +0 -5
  107. data/test/gemloader.rb +0 -10
  108. data/test/multipart/bad_robots +0 -259
  109. data/test/multipart/binary +0 -0
  110. data/test/multipart/content_type_and_no_filename +0 -6
  111. data/test/multipart/empty +0 -10
  112. data/test/multipart/fail_16384_nofile +0 -814
  113. data/test/multipart/file1.txt +0 -1
  114. data/test/multipart/filename_and_modification_param +0 -7
  115. data/test/multipart/filename_with_escaped_quotes +0 -6
  116. data/test/multipart/filename_with_escaped_quotes_and_modification_param +0 -7
  117. data/test/multipart/filename_with_percent_escaped_quotes +0 -6
  118. data/test/multipart/filename_with_unescaped_percentages +0 -6
  119. data/test/multipart/filename_with_unescaped_percentages2 +0 -6
  120. data/test/multipart/filename_with_unescaped_percentages3 +0 -6
  121. data/test/multipart/filename_with_unescaped_quotes +0 -6
  122. data/test/multipart/ie +0 -6
  123. data/test/multipart/mixed_files +0 -21
  124. data/test/multipart/nested +0 -10
  125. data/test/multipart/none +0 -9
  126. data/test/multipart/semicolon +0 -6
  127. data/test/multipart/text +0 -15
  128. data/test/multipart/three_files_three_fields +0 -31
  129. data/test/multipart/webkit +0 -32
  130. data/test/rackup/config.ru +0 -31
  131. data/test/registering_handler/rack/handler/registering_myself.rb +0 -8
  132. data/test/spec_auth.rb +0 -57
  133. data/test/spec_auth_basic.rb +0 -81
  134. data/test/spec_auth_digest.rb +0 -259
  135. data/test/spec_body_proxy.rb +0 -69
  136. data/test/spec_builder.rb +0 -207
  137. data/test/spec_cascade.rb +0 -61
  138. data/test/spec_cgi.rb +0 -102
  139. data/test/spec_chunked.rb +0 -87
  140. data/test/spec_commonlogger.rb +0 -57
  141. data/test/spec_conditionalget.rb +0 -102
  142. data/test/spec_config.rb +0 -22
  143. data/test/spec_content_length.rb +0 -86
  144. data/test/spec_content_type.rb +0 -45
  145. data/test/spec_deflater.rb +0 -187
  146. data/test/spec_directory.rb +0 -88
  147. data/test/spec_etag.rb +0 -98
  148. data/test/spec_fastcgi.rb +0 -107
  149. data/test/spec_file.rb +0 -200
  150. data/test/spec_handler.rb +0 -59
  151. data/test/spec_head.rb +0 -48
  152. data/test/spec_lint.rb +0 -515
  153. data/test/spec_lobster.rb +0 -58
  154. data/test/spec_lock.rb +0 -167
  155. data/test/spec_logger.rb +0 -23
  156. data/test/spec_methodoverride.rb +0 -72
  157. data/test/spec_mock.rb +0 -269
  158. data/test/spec_mongrel.rb +0 -182
  159. data/test/spec_multipart.rb +0 -479
  160. data/test/spec_nulllogger.rb +0 -23
  161. data/test/spec_recursive.rb +0 -72
  162. data/test/spec_request.rb +0 -955
  163. data/test/spec_response.rb +0 -313
  164. data/test/spec_rewindable_input.rb +0 -118
  165. data/test/spec_runtime.rb +0 -49
  166. data/test/spec_sendfile.rb +0 -90
  167. data/test/spec_server.rb +0 -121
  168. data/test/spec_session_abstract_id.rb +0 -43
  169. data/test/spec_session_cookie.rb +0 -361
  170. data/test/spec_session_memcache.rb +0 -321
  171. data/test/spec_session_pool.rb +0 -209
  172. data/test/spec_showexceptions.rb +0 -92
  173. data/test/spec_showstatus.rb +0 -84
  174. data/test/spec_static.rb +0 -145
  175. data/test/spec_thin.rb +0 -86
  176. data/test/spec_urlmap.rb +0 -213
  177. data/test/spec_utils.rb +0 -554
  178. data/test/spec_webrick.rb +0 -143
  179. data/test/static/another/index.html +0 -1
  180. data/test/static/index.html +0 -1
  181. data/test/testrequest.rb +0 -78
  182. data/test/unregistered_handler/rack/handler/unregistered.rb +0 -7
  183. data/test/unregistered_handler/rack/handler/unregistered_long_one.rb +0 -7
@@ -1,52 +0,0 @@
1
- # :stopdoc:
2
-
3
- # Stolen from ruby core's uri/common.rb @32618ba to fix DoS issues in 1.9.2
4
- #
5
- # https://github.com/ruby/ruby/blob/32618ba7438a2247042bba9b5d85b5d49070f5e5/lib/uri/common.rb
6
- #
7
- # Issue:
8
- # http://redmine.ruby-lang.org/issues/5149
9
- #
10
- # Relevant Fixes:
11
- # https://github.com/ruby/ruby/commit/b5f91deee04aa6ccbe07c23c8222b937c22a799b
12
- # https://github.com/ruby/ruby/commit/93177c1e5c3906abf14472ae0b905d8b5c72ce1b
13
- #
14
- # This should probably be removed once there is a Ruby 1.9.2 patch level that
15
- # includes this fix.
16
-
17
- require 'uri/common'
18
-
19
- module URI
20
- TBLDECWWWCOMP_ = {} unless const_defined?(:TBLDECWWWCOMP_) #:nodoc:
21
- if TBLDECWWWCOMP_.empty?
22
- 256.times do |i|
23
- h, l = i>>4, i&15
24
- TBLDECWWWCOMP_['%%%X%X' % [h, l]] = i.chr
25
- TBLDECWWWCOMP_['%%%x%X' % [h, l]] = i.chr
26
- TBLDECWWWCOMP_['%%%X%x' % [h, l]] = i.chr
27
- TBLDECWWWCOMP_['%%%x%x' % [h, l]] = i.chr
28
- end
29
- TBLDECWWWCOMP_['+'] = ' '
30
- TBLDECWWWCOMP_.freeze
31
- end
32
-
33
- def self.decode_www_form(str, enc=Encoding::UTF_8)
34
- return [] if str.empty?
35
- unless /\A#{WFKV_}=#{WFKV_}(?:[;&]#{WFKV_}=#{WFKV_})*\z/o =~ str
36
- raise ArgumentError, "invalid data of application/x-www-form-urlencoded (#{str})"
37
- end
38
- ary = []
39
- $&.scan(/([^=;&]+)=([^;&]*)/) do
40
- ary << [decode_www_form_component($1, enc), decode_www_form_component($2, enc)]
41
- end
42
- ary
43
- end
44
-
45
- def self.decode_www_form_component(str, enc=Encoding::UTF_8)
46
- raise ArgumentError, "invalid %-encoding (#{str})" unless /\A[^%]*(?:%\h\h[^%]*)*\z/ =~ str
47
- str.gsub(/\+|%\h\h/, TBLDECWWWCOMP_).force_encoding(enc)
48
- end
49
-
50
- remove_const :WFKV_ if const_defined?(:WFKV_)
51
- WFKV_ = '(?:[^%#=;&]*(?:%\h\h[^%#=;&]*)*)' # :nodoc:
52
- end
@@ -1,29 +0,0 @@
1
- # :stopdoc:
2
-
3
- require 'uri/common'
4
-
5
- # Issue:
6
- # http://bugs.ruby-lang.org/issues/5925
7
- #
8
- # Relevant commit:
9
- # https://github.com/ruby/ruby/commit/edb7cdf1eabaff78dfa5ffedfbc2e91b29fa9ca1
10
-
11
- module URI
12
- 256.times do |i|
13
- TBLENCWWWCOMP_[i.chr] = '%%%02X' % i
14
- end
15
- TBLENCWWWCOMP_[' '] = '+'
16
- TBLENCWWWCOMP_.freeze
17
-
18
- 256.times do |i|
19
- h, l = i>>4, i&15
20
- TBLDECWWWCOMP_['%%%X%X' % [h, l]] = i.chr
21
- TBLDECWWWCOMP_['%%%x%X' % [h, l]] = i.chr
22
- TBLDECWWWCOMP_['%%%X%x' % [h, l]] = i.chr
23
- TBLDECWWWCOMP_['%%%x%x' % [h, l]] = i.chr
24
- end
25
- TBLDECWWWCOMP_['+'] = ' '
26
- TBLDECWWWCOMP_.freeze
27
- end
28
-
29
- # :startdoc:
@@ -1,8 +0,0 @@
1
- require 'swiftcore/evented_mongrel'
2
-
3
- module Rack
4
- module Handler
5
- class EventedMongrel < Handler::Mongrel
6
- end
7
- end
8
- end
@@ -1,100 +0,0 @@
1
- require 'mongrel'
2
- require 'stringio'
3
- require 'rack/content_length'
4
- require 'rack/chunked'
5
-
6
- module Rack
7
- module Handler
8
- class Mongrel < ::Mongrel::HttpHandler
9
- def self.run(app, options={})
10
- server = ::Mongrel::HttpServer.new(
11
- options[:Host] || '0.0.0.0',
12
- options[:Port] || 8080,
13
- options[:num_processors] || 950,
14
- options[:throttle] || 0,
15
- options[:timeout] || 60)
16
- # Acts like Rack::URLMap, utilizing Mongrel's own path finding methods.
17
- # Use is similar to #run, replacing the app argument with a hash of
18
- # { path=>app, ... } or an instance of Rack::URLMap.
19
- if options[:map]
20
- if app.is_a? Hash
21
- app.each do |path, appl|
22
- path = '/'+path unless path[0] == ?/
23
- server.register(path, Rack::Handler::Mongrel.new(appl))
24
- end
25
- elsif app.is_a? URLMap
26
- app.instance_variable_get(:@mapping).each do |(host, path, appl)|
27
- next if !host.nil? && !options[:Host].nil? && options[:Host] != host
28
- path = '/'+path unless path[0] == ?/
29
- server.register(path, Rack::Handler::Mongrel.new(appl))
30
- end
31
- else
32
- raise ArgumentError, "first argument should be a Hash or URLMap"
33
- end
34
- else
35
- server.register('/', Rack::Handler::Mongrel.new(app))
36
- end
37
- yield server if block_given?
38
- server.run.join
39
- end
40
-
41
- def self.valid_options
42
- {
43
- "Host=HOST" => "Hostname to listen on (default: localhost)",
44
- "Port=PORT" => "Port to listen on (default: 8080)",
45
- "Processors=N" => "Number of concurrent processors to accept (default: 950)",
46
- "Timeout=N" => "Time before a request is dropped for inactivity (default: 60)",
47
- "Throttle=N" => "Throttle time between socket.accept calls in hundredths of a second (default: 0)",
48
- }
49
- end
50
-
51
- def initialize(app)
52
- @app = app
53
- end
54
-
55
- def process(request, response)
56
- env = {}.replace(request.params)
57
- env.delete "HTTP_CONTENT_TYPE"
58
- env.delete "HTTP_CONTENT_LENGTH"
59
-
60
- env["SCRIPT_NAME"] = "" if env["SCRIPT_NAME"] == "/"
61
-
62
- rack_input = request.body || StringIO.new('')
63
- rack_input.set_encoding(Encoding::BINARY) if rack_input.respond_to?(:set_encoding)
64
-
65
- env.update({"rack.version" => Rack::VERSION,
66
- "rack.input" => rack_input,
67
- "rack.errors" => $stderr,
68
-
69
- "rack.multithread" => true,
70
- "rack.multiprocess" => false, # ???
71
- "rack.run_once" => false,
72
-
73
- "rack.url_scheme" => ["yes", "on", "1"].include?(env["HTTPS"]) ? "https" : "http"
74
- })
75
- env["QUERY_STRING"] ||= ""
76
-
77
- status, headers, body = @app.call(env)
78
-
79
- begin
80
- response.status = status.to_i
81
- response.send_status(nil)
82
-
83
- headers.each { |k, vs|
84
- vs.split("\n").each { |v|
85
- response.header[k] = v
86
- }
87
- }
88
- response.send_header
89
-
90
- body.each { |part|
91
- response.write part
92
- response.socket.flush
93
- }
94
- ensure
95
- body.close if body.respond_to? :close
96
- end
97
- end
98
- end
99
- end
100
- end
@@ -1,8 +0,0 @@
1
- require 'swiftcore/swiftiplied_mongrel'
2
-
3
- module Rack
4
- module Handler
5
- class SwiftipliedMongrel < Handler::Mongrel
6
- end
7
- end
8
- end
@@ -1,33 +0,0 @@
1
- module Rack
2
- class MethodOverride
3
- HTTP_METHODS = %w(GET HEAD PUT POST DELETE OPTIONS PATCH)
4
-
5
- METHOD_OVERRIDE_PARAM_KEY = "_method".freeze
6
- HTTP_METHOD_OVERRIDE_HEADER = "HTTP_X_HTTP_METHOD_OVERRIDE".freeze
7
-
8
- def initialize(app)
9
- @app = app
10
- end
11
-
12
- def call(env)
13
- if env["REQUEST_METHOD"] == "POST"
14
- method = method_override(env)
15
- if HTTP_METHODS.include?(method)
16
- env["rack.methodoverride.original_method"] = env["REQUEST_METHOD"]
17
- env["REQUEST_METHOD"] = method
18
- end
19
- end
20
-
21
- @app.call(env)
22
- end
23
-
24
- def method_override(env)
25
- req = Request.new(env)
26
- method = req.POST[METHOD_OVERRIDE_PARAM_KEY] ||
27
- env[HTTP_METHOD_OVERRIDE_HEADER]
28
- method.to_s.upcase
29
- rescue EOFError
30
- ""
31
- end
32
- end
33
- end
@@ -1,18 +0,0 @@
1
- module Rack
2
- class NullLogger
3
- def initialize(app)
4
- @app = app
5
- end
6
-
7
- def call(env)
8
- env['rack.logger'] = self
9
- @app.call(env)
10
- end
11
-
12
- def info(progname = nil, &block); end
13
- def debug(progname = nil, &block); end
14
- def warn(progname = nil, &block); end
15
- def error(progname = nil, &block); end
16
- def fatal(progname = nil, &block); end
17
- end
18
- end
@@ -1,378 +0,0 @@
1
- require 'ostruct'
2
- require 'erb'
3
- require 'rack/request'
4
- require 'rack/utils'
5
-
6
- module Rack
7
- # Rack::ShowExceptions catches all exceptions raised from the app it
8
- # wraps. It shows a useful backtrace with the sourcefile and
9
- # clickable context, the whole Rack environment and the request
10
- # data.
11
- #
12
- # Be careful when you use this on public-facing sites as it could
13
- # reveal information helpful to attackers.
14
-
15
- class ShowExceptions
16
- CONTEXT = 7
17
-
18
- def initialize(app)
19
- @app = app
20
- @template = ERB.new(TEMPLATE)
21
- end
22
-
23
- def call(env)
24
- @app.call(env)
25
- rescue StandardError, LoadError, SyntaxError => e
26
- exception_string = dump_exception(e)
27
-
28
- env["rack.errors"].puts(exception_string)
29
- env["rack.errors"].flush
30
-
31
- if prefers_plain_text?(env)
32
- content_type = "text/plain"
33
- body = [exception_string]
34
- else
35
- content_type = "text/html"
36
- body = pretty(env, e)
37
- end
38
-
39
- [500,
40
- {"Content-Type" => content_type,
41
- "Content-Length" => Rack::Utils.bytesize(body.join).to_s},
42
- body]
43
- end
44
-
45
- def prefers_plain_text?(env)
46
- env["HTTP_X_REQUESTED_WITH"] == "XMLHttpRequest" && (!env["HTTP_ACCEPT"] || !env["HTTP_ACCEPT"].include?("text/html"))
47
- end
48
-
49
- def dump_exception(exception)
50
- string = "#{exception.class}: #{exception.message}\n"
51
- string << exception.backtrace.map { |l| "\t#{l}" }.join("\n")
52
- string
53
- end
54
-
55
- def pretty(env, exception)
56
- req = Rack::Request.new(env)
57
-
58
- # This double assignment is to prevent an "unused variable" warning on
59
- # Ruby 1.9.3. Yes, it is dumb, but I don't like Ruby yelling at me.
60
- path = path = (req.script_name + req.path_info).squeeze("/")
61
-
62
- # This double assignment is to prevent an "unused variable" warning on
63
- # Ruby 1.9.3. Yes, it is dumb, but I don't like Ruby yelling at me.
64
- frames = frames = exception.backtrace.map { |line|
65
- frame = OpenStruct.new
66
- if line =~ /(.*?):(\d+)(:in `(.*)')?/
67
- frame.filename = $1
68
- frame.lineno = $2.to_i
69
- frame.function = $4
70
-
71
- begin
72
- lineno = frame.lineno-1
73
- lines = ::File.readlines(frame.filename)
74
- frame.pre_context_lineno = [lineno-CONTEXT, 0].max
75
- frame.pre_context = lines[frame.pre_context_lineno...lineno]
76
- frame.context_line = lines[lineno].chomp
77
- frame.post_context_lineno = [lineno+CONTEXT, lines.size].min
78
- frame.post_context = lines[lineno+1..frame.post_context_lineno]
79
- rescue
80
- end
81
-
82
- frame
83
- else
84
- nil
85
- end
86
- }.compact
87
-
88
- [@template.result(binding)]
89
- end
90
-
91
- def h(obj) # :nodoc:
92
- case obj
93
- when String
94
- Utils.escape_html(obj)
95
- else
96
- Utils.escape_html(obj.inspect)
97
- end
98
- end
99
-
100
- # :stopdoc:
101
-
102
- # adapted from Django <djangoproject.com>
103
- # Copyright (c) 2005, the Lawrence Journal-World
104
- # Used under the modified BSD license:
105
- # http://www.xfree86.org/3.3.6/COPYRIGHT2.html#5
106
- TEMPLATE = <<'HTML'
107
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
108
- <html lang="en">
109
- <head>
110
- <meta http-equiv="content-type" content="text/html; charset=utf-8" />
111
- <meta name="robots" content="NONE,NOARCHIVE" />
112
- <title><%=h exception.class %> at <%=h path %></title>
113
- <style type="text/css">
114
- html * { padding:0; margin:0; }
115
- body * { padding:10px 20px; }
116
- body * * { padding:0; }
117
- body { font:small sans-serif; }
118
- body>div { border-bottom:1px solid #ddd; }
119
- h1 { font-weight:normal; }
120
- h2 { margin-bottom:.8em; }
121
- h2 span { font-size:80%; color:#666; font-weight:normal; }
122
- h3 { margin:1em 0 .5em 0; }
123
- h4 { margin:0 0 .5em 0; font-weight: normal; }
124
- table {
125
- border:1px solid #ccc; border-collapse: collapse; background:white; }
126
- tbody td, tbody th { vertical-align:top; padding:2px 3px; }
127
- thead th {
128
- padding:1px 6px 1px 3px; background:#fefefe; text-align:left;
129
- font-weight:normal; font-size:11px; border:1px solid #ddd; }
130
- tbody th { text-align:right; color:#666; padding-right:.5em; }
131
- table.vars { margin:5px 0 2px 40px; }
132
- table.vars td, table.req td { font-family:monospace; }
133
- table td.code { width:100%;}
134
- table td.code div { overflow:hidden; }
135
- table.source th { color:#666; }
136
- table.source td {
137
- font-family:monospace; white-space:pre; border-bottom:1px solid #eee; }
138
- ul.traceback { list-style-type:none; }
139
- ul.traceback li.frame { margin-bottom:1em; }
140
- div.context { margin: 10px 0; }
141
- div.context ol {
142
- padding-left:30px; margin:0 10px; list-style-position: inside; }
143
- div.context ol li {
144
- font-family:monospace; white-space:pre; color:#666; cursor:pointer; }
145
- div.context ol.context-line li { color:black; background-color:#ccc; }
146
- div.context ol.context-line li span { float: right; }
147
- div.commands { margin-left: 40px; }
148
- div.commands a { color:black; text-decoration:none; }
149
- #summary { background: #ffc; }
150
- #summary h2 { font-weight: normal; color: #666; }
151
- #summary ul#quicklinks { list-style-type: none; margin-bottom: 2em; }
152
- #summary ul#quicklinks li { float: left; padding: 0 1em; }
153
- #summary ul#quicklinks>li+li { border-left: 1px #666 solid; }
154
- #explanation { background:#eee; }
155
- #template, #template-not-exist { background:#f6f6f6; }
156
- #template-not-exist ul { margin: 0 0 0 20px; }
157
- #traceback { background:#eee; }
158
- #requestinfo { background:#f6f6f6; padding-left:120px; }
159
- #summary table { border:none; background:transparent; }
160
- #requestinfo h2, #requestinfo h3 { position:relative; margin-left:-100px; }
161
- #requestinfo h3 { margin-bottom:-1em; }
162
- .error { background: #ffc; }
163
- .specific { color:#cc3300; font-weight:bold; }
164
- </style>
165
- <script type="text/javascript">
166
- //<!--
167
- function getElementsByClassName(oElm, strTagName, strClassName){
168
- // Written by Jonathan Snook, http://www.snook.ca/jon;
169
- // Add-ons by Robert Nyman, http://www.robertnyman.com
170
- var arrElements = (strTagName == "*" && document.all)? document.all :
171
- oElm.getElementsByTagName(strTagName);
172
- var arrReturnElements = new Array();
173
- strClassName = strClassName.replace(/\-/g, "\\-");
174
- var oRegExp = new RegExp("(^|\\s)" + strClassName + "(\\s|$$)");
175
- var oElement;
176
- for(var i=0; i<arrElements.length; i++){
177
- oElement = arrElements[i];
178
- if(oRegExp.test(oElement.className)){
179
- arrReturnElements.push(oElement);
180
- }
181
- }
182
- return (arrReturnElements)
183
- }
184
- function hideAll(elems) {
185
- for (var e = 0; e < elems.length; e++) {
186
- elems[e].style.display = 'none';
187
- }
188
- }
189
- window.onload = function() {
190
- hideAll(getElementsByClassName(document, 'table', 'vars'));
191
- hideAll(getElementsByClassName(document, 'ol', 'pre-context'));
192
- hideAll(getElementsByClassName(document, 'ol', 'post-context'));
193
- }
194
- function toggle() {
195
- for (var i = 0; i < arguments.length; i++) {
196
- var e = document.getElementById(arguments[i]);
197
- if (e) {
198
- e.style.display = e.style.display == 'none' ? 'block' : 'none';
199
- }
200
- }
201
- return false;
202
- }
203
- function varToggle(link, id) {
204
- toggle('v' + id);
205
- var s = link.getElementsByTagName('span')[0];
206
- var uarr = String.fromCharCode(0x25b6);
207
- var darr = String.fromCharCode(0x25bc);
208
- s.innerHTML = s.innerHTML == uarr ? darr : uarr;
209
- return false;
210
- }
211
- //-->
212
- </script>
213
- </head>
214
- <body>
215
-
216
- <div id="summary">
217
- <h1><%=h exception.class %> at <%=h path %></h1>
218
- <h2><%=h exception.message %></h2>
219
- <table><tr>
220
- <th>Ruby</th>
221
- <td>
222
- <% if first = frames.first %>
223
- <code><%=h first.filename %></code>: in <code><%=h first.function %></code>, line <%=h frames.first.lineno %>
224
- <% else %>
225
- unknown location
226
- <% end %>
227
- </td>
228
- </tr><tr>
229
- <th>Web</th>
230
- <td><code><%=h req.request_method %> <%=h(req.host + path)%></code></td>
231
- </tr></table>
232
-
233
- <h3>Jump to:</h3>
234
- <ul id="quicklinks">
235
- <li><a href="#get-info">GET</a></li>
236
- <li><a href="#post-info">POST</a></li>
237
- <li><a href="#cookie-info">Cookies</a></li>
238
- <li><a href="#env-info">ENV</a></li>
239
- </ul>
240
- </div>
241
-
242
- <div id="traceback">
243
- <h2>Traceback <span>(innermost first)</span></h2>
244
- <ul class="traceback">
245
- <% frames.each { |frame| %>
246
- <li class="frame">
247
- <code><%=h frame.filename %></code>: in <code><%=h frame.function %></code>
248
-
249
- <% if frame.context_line %>
250
- <div class="context" id="c<%=h frame.object_id %>">
251
- <% if frame.pre_context %>
252
- <ol start="<%=h frame.pre_context_lineno+1 %>" class="pre-context" id="pre<%=h frame.object_id %>">
253
- <% frame.pre_context.each { |line| %>
254
- <li onclick="toggle('pre<%=h frame.object_id %>', 'post<%=h frame.object_id %>')"><%=h line %></li>
255
- <% } %>
256
- </ol>
257
- <% end %>
258
-
259
- <ol start="<%=h frame.lineno %>" class="context-line">
260
- <li onclick="toggle('pre<%=h frame.object_id %>', 'post<%=h frame.object_id %>')"><%=h frame.context_line %><span>...</span></li></ol>
261
-
262
- <% if frame.post_context %>
263
- <ol start='<%=h frame.lineno+1 %>' class="post-context" id="post<%=h frame.object_id %>">
264
- <% frame.post_context.each { |line| %>
265
- <li onclick="toggle('pre<%=h frame.object_id %>', 'post<%=h frame.object_id %>')"><%=h line %></li>
266
- <% } %>
267
- </ol>
268
- <% end %>
269
- </div>
270
- <% end %>
271
- </li>
272
- <% } %>
273
- </ul>
274
- </div>
275
-
276
- <div id="requestinfo">
277
- <h2>Request information</h2>
278
-
279
- <h3 id="get-info">GET</h3>
280
- <% if req.GET and not req.GET.empty? %>
281
- <table class="req">
282
- <thead>
283
- <tr>
284
- <th>Variable</th>
285
- <th>Value</th>
286
- </tr>
287
- </thead>
288
- <tbody>
289
- <% req.GET.sort_by { |k, v| k.to_s }.each { |key, val| %>
290
- <tr>
291
- <td><%=h key %></td>
292
- <td class="code"><div><%=h val.inspect %></div></td>
293
- </tr>
294
- <% } %>
295
- </tbody>
296
- </table>
297
- <% else %>
298
- <p>No GET data.</p>
299
- <% end %>
300
-
301
- <h3 id="post-info">POST</h3>
302
- <% if req.POST and not req.POST.empty? %>
303
- <table class="req">
304
- <thead>
305
- <tr>
306
- <th>Variable</th>
307
- <th>Value</th>
308
- </tr>
309
- </thead>
310
- <tbody>
311
- <% req.POST.sort_by { |k, v| k.to_s }.each { |key, val| %>
312
- <tr>
313
- <td><%=h key %></td>
314
- <td class="code"><div><%=h val.inspect %></div></td>
315
- </tr>
316
- <% } %>
317
- </tbody>
318
- </table>
319
- <% else %>
320
- <p>No POST data.</p>
321
- <% end %>
322
-
323
-
324
- <h3 id="cookie-info">COOKIES</h3>
325
- <% unless req.cookies.empty? %>
326
- <table class="req">
327
- <thead>
328
- <tr>
329
- <th>Variable</th>
330
- <th>Value</th>
331
- </tr>
332
- </thead>
333
- <tbody>
334
- <% req.cookies.each { |key, val| %>
335
- <tr>
336
- <td><%=h key %></td>
337
- <td class="code"><div><%=h val.inspect %></div></td>
338
- </tr>
339
- <% } %>
340
- </tbody>
341
- </table>
342
- <% else %>
343
- <p>No cookie data.</p>
344
- <% end %>
345
-
346
- <h3 id="env-info">Rack ENV</h3>
347
- <table class="req">
348
- <thead>
349
- <tr>
350
- <th>Variable</th>
351
- <th>Value</th>
352
- </tr>
353
- </thead>
354
- <tbody>
355
- <% env.sort_by { |k, v| k.to_s }.each { |key, val| %>
356
- <tr>
357
- <td><%=h key %></td>
358
- <td class="code"><div><%=h val %></div></td>
359
- </tr>
360
- <% } %>
361
- </tbody>
362
- </table>
363
-
364
- </div>
365
-
366
- <div id="explanation">
367
- <p>
368
- You're seeing this error because you use <code>Rack::ShowExceptions</code>.
369
- </p>
370
- </div>
371
-
372
- </body>
373
- </html>
374
- HTML
375
-
376
- # :startdoc:
377
- end
378
- end
@@ -1,5 +0,0 @@
1
- class Anything
2
- def self.call(env)
3
- [200, {'Content-Type' => 'text/plain'}, ['OK']]
4
- end
5
- end
@@ -1,4 +0,0 @@
1
- =begin
2
-
3
- =end
4
- run lambda { |env| [200, {'Content-Type' => 'text/plain'}, ['OK']] }
data/test/builder/end.ru DELETED
@@ -1,5 +0,0 @@
1
- run lambda { |env| [200, {'Content-Type' => 'text/plain'}, ['OK']] }
2
- __END__
3
- Should not be evaluated
4
- Neither should
5
- This
data/test/builder/line.ru DELETED
@@ -1 +0,0 @@
1
- run lambda{ |env| [200, {'Content-Type' => 'text/plain'}, [__LINE__.to_s]] }
@@ -1,2 +0,0 @@
1
- #\ -d
2
- run lambda { |env| [200, {'Content-Type' => 'text/plain'}, ['OK']] }
@@ -1 +0,0 @@
1
- ### TestFile ###
@@ -1 +0,0 @@
1
- ### TestFile ###
@@ -1 +0,0 @@
1
- ### TestFile ###
@@ -1 +0,0 @@
1
- ### TestFile ###
@@ -1 +0,0 @@
1
- ### TestFile ###
@@ -1 +0,0 @@
1
- ### TestFile ###