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,12 +1,35 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'webrick'
2
4
  require 'stringio'
3
5
  require 'rack/content_length'
4
6
 
7
+ # This monkey patch allows for applications to perform their own chunking
8
+ # through WEBrick::HTTPResponse if rack is set to true.
9
+ class WEBrick::HTTPResponse
10
+ attr_accessor :rack
11
+
12
+ alias _rack_setup_header setup_header
13
+ def setup_header
14
+ app_chunking = rack && @header['transfer-encoding'] == 'chunked'
15
+
16
+ @chunked = app_chunking if app_chunking
17
+
18
+ _rack_setup_header
19
+
20
+ @chunked = false if app_chunking
21
+ end
22
+ end
23
+
5
24
  module Rack
6
25
  module Handler
7
26
  class WEBrick < ::WEBrick::HTTPServlet::AbstractServlet
8
- def self.run(app, options={})
9
- options[:BindAddress] = options.delete(:Host) if options[:Host]
27
+ def self.run(app, options = {})
28
+ environment = ENV['RACK_ENV'] || 'development'
29
+ default_host = environment == 'development' ? 'localhost' : nil
30
+
31
+ options[:BindAddress] = options.delete(:Host) || default_host
32
+ options[:Port] ||= 8080
10
33
  @server = ::WEBrick::HTTPServer.new(options)
11
34
  @server.mount "/", Rack::Handler::WEBrick, app
12
35
  yield @server if block_given?
@@ -14,8 +37,11 @@ module Rack
14
37
  end
15
38
 
16
39
  def self.valid_options
40
+ environment = ENV['RACK_ENV'] || 'development'
41
+ default_host = environment == 'development' ? 'localhost' : '0.0.0.0'
42
+
17
43
  {
18
- "Host=HOST" => "Hostname to listen on (default: localhost)",
44
+ "Host=HOST" => "Hostname to listen on (default: #{default_host})",
19
45
  "Port=PORT" => "Port to listen on (default: 8080)",
20
46
  }
21
47
  end
@@ -31,36 +57,42 @@ module Rack
31
57
  end
32
58
 
33
59
  def service(req, res)
60
+ res.rack = true
34
61
  env = req.meta_vars
35
62
  env.delete_if { |k, v| v.nil? }
36
63
 
37
64
  rack_input = StringIO.new(req.body.to_s)
38
- rack_input.set_encoding(Encoding::BINARY) if rack_input.respond_to?(:set_encoding)
39
-
40
- env.update({"rack.version" => Rack::VERSION,
41
- "rack.input" => rack_input,
42
- "rack.errors" => $stderr,
65
+ rack_input.set_encoding(Encoding::BINARY)
43
66
 
44
- "rack.multithread" => true,
45
- "rack.multiprocess" => false,
46
- "rack.run_once" => false,
67
+ env.update(
68
+ RACK_VERSION => Rack::VERSION,
69
+ RACK_INPUT => rack_input,
70
+ RACK_ERRORS => $stderr,
71
+ RACK_MULTITHREAD => true,
72
+ RACK_MULTIPROCESS => false,
73
+ RACK_RUNONCE => false,
74
+ RACK_URL_SCHEME => ["yes", "on", "1"].include?(env[HTTPS]) ? "https" : "http",
75
+ RACK_IS_HIJACK => true,
76
+ RACK_HIJACK => lambda { raise NotImplementedError, "only partial hijack is supported."},
77
+ RACK_HIJACK_IO => nil
78
+ )
47
79
 
48
- "rack.url_scheme" => ["yes", "on", "1"].include?(ENV["HTTPS"]) ? "https" : "http"
49
- })
50
-
51
- env["HTTP_VERSION"] ||= env["SERVER_PROTOCOL"]
52
- env["QUERY_STRING"] ||= ""
53
- unless env["PATH_INFO"] == ""
54
- path, n = req.request_uri.path, env["SCRIPT_NAME"].length
55
- env["PATH_INFO"] = path[n, path.length-n]
80
+ env[HTTP_VERSION] ||= env[SERVER_PROTOCOL]
81
+ env[QUERY_STRING] ||= ""
82
+ unless env[PATH_INFO] == ""
83
+ path, n = req.request_uri.path, env[SCRIPT_NAME].length
84
+ env[PATH_INFO] = path[n, path.length - n]
56
85
  end
57
- env["REQUEST_PATH"] ||= [env["SCRIPT_NAME"], env["PATH_INFO"]].join
86
+ env[REQUEST_PATH] ||= [env[SCRIPT_NAME], env[PATH_INFO]].join
58
87
 
59
88
  status, headers, body = @app.call(env)
60
89
  begin
61
90
  res.status = status.to_i
91
+ io_lambda = nil
62
92
  headers.each { |k, vs|
63
- if k.downcase == "set-cookie"
93
+ if k == RACK_HIJACK
94
+ io_lambda = vs
95
+ elsif k.downcase == "set-cookie"
64
96
  res.cookies.concat vs.split("\n")
65
97
  else
66
98
  # Since WEBrick won't accept repeated headers,
@@ -68,9 +100,19 @@ module Rack
68
100
  res[k] = vs.split("\n").join(", ")
69
101
  end
70
102
  }
71
- body.each { |part|
72
- res.body << part
73
- }
103
+
104
+ if io_lambda
105
+ rd, wr = IO.pipe
106
+ res.body = rd
107
+ res.chunked = true
108
+ io_lambda.call wr
109
+ elsif body.respond_to?(:to_path)
110
+ res.body = ::File.open(body.to_path, 'rb')
111
+ else
112
+ body.each { |part|
113
+ res.body << part
114
+ }
115
+ end
74
116
  ensure
75
117
  body.close if body.respond_to? :close
76
118
  end
data/lib/rack/handler.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rack
2
4
  # *Handlers* connect web servers with Rack.
3
5
  #
@@ -17,31 +19,45 @@ module Rack
17
19
  end
18
20
 
19
21
  if klass = @handlers[server]
20
- klass.split("::").inject(Object) { |o, x| o.const_get(x) }
22
+ const_get(klass)
21
23
  else
22
- const_get(server)
24
+ const_get(server, false)
23
25
  end
24
26
 
25
27
  rescue NameError => name_error
26
28
  raise load_error || name_error
27
29
  end
28
30
 
29
- def self.default(options = {})
31
+ # Select first available Rack handler given an `Array` of server names.
32
+ # Raises `LoadError` if no handler was found.
33
+ #
34
+ # > pick ['thin', 'webrick']
35
+ # => Rack::Handler::WEBrick
36
+ def self.pick(server_names)
37
+ server_names = Array(server_names)
38
+ server_names.each do |server_name|
39
+ begin
40
+ return get(server_name.to_s)
41
+ rescue LoadError, NameError
42
+ end
43
+ end
44
+
45
+ raise LoadError, "Couldn't find handler for: #{server_names.join(', ')}."
46
+ end
47
+
48
+ SERVER_NAMES = %w(puma thin falcon webrick).freeze
49
+ private_constant :SERVER_NAMES
50
+
51
+ def self.default
30
52
  # Guess.
31
53
  if ENV.include?("PHP_FCGI_CHILDREN")
32
- # We already speak FastCGI
33
- options.delete :File
34
- options.delete :Port
35
-
36
54
  Rack::Handler::FastCGI
37
- elsif ENV.include?("REQUEST_METHOD")
55
+ elsif ENV.include?(REQUEST_METHOD)
38
56
  Rack::Handler::CGI
57
+ elsif ENV.include?("RACK_HANDLER")
58
+ self.get(ENV["RACK_HANDLER"])
39
59
  else
40
- begin
41
- Rack::Handler::Thin
42
- rescue LoadError
43
- Rack::Handler::WEBrick
44
- end
60
+ pick SERVER_NAMES
45
61
  end
46
62
  end
47
63
 
@@ -73,9 +89,6 @@ module Rack
73
89
 
74
90
  autoload :CGI, "rack/handler/cgi"
75
91
  autoload :FastCGI, "rack/handler/fastcgi"
76
- autoload :Mongrel, "rack/handler/mongrel"
77
- autoload :EventedMongrel, "rack/handler/evented_mongrel"
78
- autoload :SwiftipliedMongrel, "rack/handler/swiftiplied_mongrel"
79
92
  autoload :WEBrick, "rack/handler/webrick"
80
93
  autoload :LSWS, "rack/handler/lsws"
81
94
  autoload :SCGI, "rack/handler/scgi"
@@ -83,9 +96,6 @@ module Rack
83
96
 
84
97
  register 'cgi', 'Rack::Handler::CGI'
85
98
  register 'fastcgi', 'Rack::Handler::FastCGI'
86
- register 'mongrel', 'Rack::Handler::Mongrel'
87
- register 'emongrel', 'Rack::Handler::EventedMongrel'
88
- register 'smongrel', 'Rack::Handler::SwiftipliedMongrel'
89
99
  register 'webrick', 'Rack::Handler::WEBrick'
90
100
  register 'lsws', 'Rack::Handler::LSWS'
91
101
  register 'scgi', 'Rack::Handler::SCGI'
data/lib/rack/head.rb CHANGED
@@ -1,20 +1,27 @@
1
- module Rack
1
+ # frozen_string_literal: true
2
2
 
3
- class Head
4
- def initialize(app)
5
- @app = app
6
- end
3
+ require 'rack/body_proxy'
7
4
 
8
- def call(env)
9
- status, headers, body = @app.call(env)
5
+ module Rack
6
+ # Rack::Head returns an empty body for all HEAD requests. It leaves
7
+ # all other requests unchanged.
8
+ class Head
9
+ def initialize(app)
10
+ @app = app
11
+ end
10
12
 
11
- if env["REQUEST_METHOD"] == "HEAD"
12
- body.close if body.respond_to? :close
13
- [status, headers, []]
14
- else
15
- [status, headers, body]
13
+ def call(env)
14
+ status, headers, body = @app.call(env)
15
+
16
+ if env[REQUEST_METHOD] == HEAD
17
+ [
18
+ status, headers, Rack::BodyProxy.new([]) do
19
+ body.close if body.respond_to? :close
20
+ end
21
+ ]
22
+ else
23
+ [status, headers, body]
24
+ end
16
25
  end
17
26
  end
18
27
  end
19
-
20
- end