rack 1.0.1 → 2.2.21

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 (147) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +829 -0
  3. data/CONTRIBUTING.md +136 -0
  4. data/{COPYING → MIT-LICENSE} +4 -2
  5. data/README.rdoc +355 -0
  6. data/Rakefile +64 -98
  7. data/SPEC.rdoc +292 -0
  8. data/bin/rackup +3 -174
  9. data/contrib/rack.png +0 -0
  10. data/contrib/rack.svg +150 -0
  11. data/contrib/rack_logo.svg +164 -111
  12. data/contrib/rdoc.css +412 -0
  13. data/example/lobster.ru +2 -0
  14. data/example/protectedlobster.rb +4 -2
  15. data/example/protectedlobster.ru +3 -1
  16. data/lib/rack/auth/abstract/handler.rb +7 -5
  17. data/lib/rack/auth/abstract/request.rb +12 -2
  18. data/lib/rack/auth/basic.rb +6 -4
  19. data/lib/rack/auth/digest/md5.rb +20 -13
  20. data/lib/rack/auth/digest/nonce.rb +6 -4
  21. data/lib/rack/auth/digest/params.rb +11 -12
  22. data/lib/rack/auth/digest/request.rb +15 -12
  23. data/lib/rack/body_proxy.rb +45 -0
  24. data/lib/rack/builder.rb +213 -19
  25. data/lib/rack/cascade.rb +50 -18
  26. data/lib/rack/chunked.rb +95 -27
  27. data/lib/rack/common_logger.rb +84 -0
  28. data/lib/rack/conditional_get.rb +83 -0
  29. data/lib/rack/config.rb +22 -0
  30. data/lib/rack/content_length.rb +19 -10
  31. data/lib/rack/content_type.rb +12 -5
  32. data/lib/rack/core_ext/regexp.rb +14 -0
  33. data/lib/rack/deflater.rb +90 -42
  34. data/lib/rack/directory.rb +118 -72
  35. data/lib/rack/etag.rb +77 -0
  36. data/lib/rack/events.rb +153 -0
  37. data/lib/rack/file.rb +4 -85
  38. data/lib/rack/files.rb +218 -0
  39. data/lib/rack/handler/cgi.rb +22 -24
  40. data/lib/rack/handler/fastcgi.rb +34 -24
  41. data/lib/rack/handler/lsws.rb +16 -15
  42. data/lib/rack/handler/scgi.rb +38 -29
  43. data/lib/rack/handler/thin.rb +23 -7
  44. data/lib/rack/handler/webrick.rb +95 -37
  45. data/lib/rack/handler.rb +49 -14
  46. data/lib/rack/head.rb +19 -13
  47. data/lib/rack/lint.rb +466 -217
  48. data/lib/rack/lobster.rb +19 -14
  49. data/lib/rack/lock.rb +24 -8
  50. data/lib/rack/logger.rb +20 -0
  51. data/lib/rack/media_type.rb +53 -0
  52. data/lib/rack/method_override.rb +52 -0
  53. data/lib/rack/mime.rb +652 -171
  54. data/lib/rack/mock.rb +203 -64
  55. data/lib/rack/multipart/generator.rb +97 -0
  56. data/lib/rack/multipart/parser.rb +440 -0
  57. data/lib/rack/multipart/uploaded_file.rb +41 -0
  58. data/lib/rack/multipart.rb +64 -0
  59. data/lib/rack/null_logger.rb +39 -0
  60. data/lib/rack/query_parser.rb +266 -0
  61. data/lib/rack/recursive.rb +18 -11
  62. data/lib/rack/reloader.rb +13 -5
  63. data/lib/rack/request.rb +607 -191
  64. data/lib/rack/response.rb +245 -110
  65. data/lib/rack/rewindable_input.rb +15 -21
  66. data/lib/rack/runtime.rb +34 -0
  67. data/lib/rack/sendfile.rb +192 -0
  68. data/lib/rack/server.rb +466 -0
  69. data/lib/rack/session/abstract/id.rb +449 -68
  70. data/lib/rack/session/cookie.rb +159 -47
  71. data/lib/rack/session/memcache.rb +4 -103
  72. data/lib/rack/session/pool.rb +39 -49
  73. data/lib/rack/show_exceptions.rb +390 -0
  74. data/lib/rack/{showstatus.rb → show_status.rb} +21 -14
  75. data/lib/rack/static.rb +164 -14
  76. data/lib/rack/tempfile_reaper.rb +22 -0
  77. data/lib/rack/urlmap.rb +60 -18
  78. data/lib/rack/utils.rb +508 -277
  79. data/lib/rack/version.rb +29 -0
  80. data/lib/rack.rb +85 -34
  81. data/rack.gemspec +43 -51
  82. metadata +119 -207
  83. data/KNOWN-ISSUES +0 -18
  84. data/RDOX +0 -428
  85. data/README +0 -364
  86. data/SPEC +0 -164
  87. data/lib/rack/adapter/camping.rb +0 -22
  88. data/lib/rack/auth/openid.rb +0 -480
  89. data/lib/rack/commonlogger.rb +0 -61
  90. data/lib/rack/conditionalget.rb +0 -47
  91. data/lib/rack/handler/evented_mongrel.rb +0 -8
  92. data/lib/rack/handler/mongrel.rb +0 -87
  93. data/lib/rack/handler/swiftiplied_mongrel.rb +0 -8
  94. data/lib/rack/methodoverride.rb +0 -27
  95. data/lib/rack/showexceptions.rb +0 -349
  96. data/test/cgi/lighttpd.conf +0 -20
  97. data/test/cgi/test +0 -9
  98. data/test/cgi/test.fcgi +0 -8
  99. data/test/cgi/test.ru +0 -7
  100. data/test/multipart/binary +0 -0
  101. data/test/multipart/empty +0 -10
  102. data/test/multipart/ie +0 -6
  103. data/test/multipart/nested +0 -10
  104. data/test/multipart/none +0 -9
  105. data/test/multipart/semicolon +0 -6
  106. data/test/multipart/text +0 -10
  107. data/test/spec_rack_auth_basic.rb +0 -73
  108. data/test/spec_rack_auth_digest.rb +0 -226
  109. data/test/spec_rack_auth_openid.rb +0 -84
  110. data/test/spec_rack_builder.rb +0 -84
  111. data/test/spec_rack_camping.rb +0 -51
  112. data/test/spec_rack_cascade.rb +0 -50
  113. data/test/spec_rack_cgi.rb +0 -89
  114. data/test/spec_rack_chunked.rb +0 -62
  115. data/test/spec_rack_commonlogger.rb +0 -32
  116. data/test/spec_rack_conditionalget.rb +0 -41
  117. data/test/spec_rack_content_length.rb +0 -43
  118. data/test/spec_rack_content_type.rb +0 -30
  119. data/test/spec_rack_deflater.rb +0 -127
  120. data/test/spec_rack_directory.rb +0 -61
  121. data/test/spec_rack_fastcgi.rb +0 -89
  122. data/test/spec_rack_file.rb +0 -75
  123. data/test/spec_rack_handler.rb +0 -43
  124. data/test/spec_rack_head.rb +0 -30
  125. data/test/spec_rack_lint.rb +0 -521
  126. data/test/spec_rack_lobster.rb +0 -45
  127. data/test/spec_rack_lock.rb +0 -38
  128. data/test/spec_rack_methodoverride.rb +0 -60
  129. data/test/spec_rack_mock.rb +0 -157
  130. data/test/spec_rack_mongrel.rb +0 -189
  131. data/test/spec_rack_recursive.rb +0 -77
  132. data/test/spec_rack_request.rb +0 -504
  133. data/test/spec_rack_response.rb +0 -218
  134. data/test/spec_rack_rewindable_input.rb +0 -118
  135. data/test/spec_rack_session_cookie.rb +0 -82
  136. data/test/spec_rack_session_memcache.rb +0 -240
  137. data/test/spec_rack_session_pool.rb +0 -172
  138. data/test/spec_rack_showexceptions.rb +0 -21
  139. data/test/spec_rack_showstatus.rb +0 -72
  140. data/test/spec_rack_static.rb +0 -37
  141. data/test/spec_rack_thin.rb +0 -91
  142. data/test/spec_rack_urlmap.rb +0 -185
  143. data/test/spec_rack_utils.rb +0 -387
  144. data/test/spec_rack_webrick.rb +0 -130
  145. data/test/testrequest.rb +0 -57
  146. data/test/unregistered_handler/rack/handler/unregistered.rb +0 -7
  147. data/test/unregistered_handler/rack/handler/unregistered_long_one.rb +0 -7
@@ -1,67 +1,125 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'webrick'
2
4
  require 'stringio'
3
- require 'rack/content_length'
5
+
6
+ # This monkey patch allows for applications to perform their own chunking
7
+ # through WEBrick::HTTPResponse if rack is set to true.
8
+ class WEBrick::HTTPResponse
9
+ attr_accessor :rack
10
+
11
+ alias _rack_setup_header setup_header
12
+ def setup_header
13
+ app_chunking = rack && @header['transfer-encoding'] == 'chunked'
14
+
15
+ @chunked = app_chunking if app_chunking
16
+
17
+ _rack_setup_header
18
+
19
+ @chunked = false if app_chunking
20
+ end
21
+ end
4
22
 
5
23
  module Rack
6
24
  module Handler
7
25
  class WEBrick < ::WEBrick::HTTPServlet::AbstractServlet
8
- def self.run(app, options={})
9
- options[:BindAddress] = options.delete(:Host) if options[:Host]
10
- server = ::WEBrick::HTTPServer.new(options)
11
- server.mount "/", Rack::Handler::WEBrick, app
12
- trap(:INT) { server.shutdown }
13
- yield server if block_given?
14
- server.start
26
+ def self.run(app, **options)
27
+ environment = ENV['RACK_ENV'] || 'development'
28
+ default_host = environment == 'development' ? 'localhost' : nil
29
+
30
+ if !options[:BindAddress] || options[:Host]
31
+ options[:BindAddress] = options.delete(:Host) || default_host
32
+ end
33
+ options[:Port] ||= 8080
34
+ if options[:SSLEnable]
35
+ require 'webrick/https'
36
+ end
37
+
38
+ @server = ::WEBrick::HTTPServer.new(options)
39
+ @server.mount "/", Rack::Handler::WEBrick, app
40
+ yield @server if block_given?
41
+ @server.start
42
+ end
43
+
44
+ def self.valid_options
45
+ environment = ENV['RACK_ENV'] || 'development'
46
+ default_host = environment == 'development' ? 'localhost' : '0.0.0.0'
47
+
48
+ {
49
+ "Host=HOST" => "Hostname to listen on (default: #{default_host})",
50
+ "Port=PORT" => "Port to listen on (default: 8080)",
51
+ }
52
+ end
53
+
54
+ def self.shutdown
55
+ if @server
56
+ @server.shutdown
57
+ @server = nil
58
+ end
15
59
  end
16
60
 
17
61
  def initialize(server, app)
18
62
  super server
19
- @app = Rack::ContentLength.new(app)
63
+ @app = app
20
64
  end
21
65
 
22
66
  def service(req, res)
67
+ res.rack = true
23
68
  env = req.meta_vars
24
69
  env.delete_if { |k, v| v.nil? }
25
70
 
26
71
  rack_input = StringIO.new(req.body.to_s)
27
- rack_input.set_encoding(Encoding::BINARY) if rack_input.respond_to?(:set_encoding)
28
-
29
- env.update({"rack.version" => [1,0],
30
- "rack.input" => rack_input,
31
- "rack.errors" => $stderr,
32
-
33
- "rack.multithread" => true,
34
- "rack.multiprocess" => false,
35
- "rack.run_once" => false,
36
-
37
- "rack.url_scheme" => ["yes", "on", "1"].include?(ENV["HTTPS"]) ? "https" : "http"
38
- })
39
-
40
- env["HTTP_VERSION"] ||= env["SERVER_PROTOCOL"]
41
- env["QUERY_STRING"] ||= ""
42
- env["REQUEST_PATH"] ||= "/"
43
- if env["PATH_INFO"] == ""
44
- env.delete "PATH_INFO"
45
- else
46
- path, n = req.request_uri.path, env["SCRIPT_NAME"].length
47
- env["PATH_INFO"] = path[n, path.length-n]
72
+ rack_input.set_encoding(Encoding::BINARY)
73
+
74
+ env.update(
75
+ RACK_VERSION => Rack::VERSION,
76
+ RACK_INPUT => rack_input,
77
+ RACK_ERRORS => $stderr,
78
+ RACK_MULTITHREAD => true,
79
+ RACK_MULTIPROCESS => false,
80
+ RACK_RUNONCE => false,
81
+ RACK_URL_SCHEME => ["yes", "on", "1"].include?(env[HTTPS]) ? "https" : "http",
82
+ RACK_IS_HIJACK => true,
83
+ RACK_HIJACK => lambda { raise NotImplementedError, "only partial hijack is supported."},
84
+ RACK_HIJACK_IO => nil
85
+ )
86
+
87
+ env[HTTP_VERSION] ||= env[SERVER_PROTOCOL]
88
+ env[QUERY_STRING] ||= ""
89
+ unless env[PATH_INFO] == ""
90
+ path, n = req.request_uri.path, env[SCRIPT_NAME].length
91
+ env[PATH_INFO] = path[n, path.length - n]
48
92
  end
93
+ env[REQUEST_PATH] ||= [env[SCRIPT_NAME], env[PATH_INFO]].join
49
94
 
50
95
  status, headers, body = @app.call(env)
51
96
  begin
52
97
  res.status = status.to_i
98
+ io_lambda = nil
53
99
  headers.each { |k, vs|
54
- if k.downcase == "set-cookie"
100
+ if k == RACK_HIJACK
101
+ io_lambda = vs
102
+ elsif k.downcase == "set-cookie"
55
103
  res.cookies.concat vs.split("\n")
56
104
  else
57
- vs.split("\n").each { |v|
58
- res[k] = v
59
- }
105
+ # Since WEBrick won't accept repeated headers,
106
+ # merge the values per RFC 1945 section 4.2.
107
+ res[k] = vs.split("\n").join(", ")
60
108
  end
61
109
  }
62
- body.each { |part|
63
- res.body << part
64
- }
110
+
111
+ if io_lambda
112
+ rd, wr = IO.pipe
113
+ res.body = rd
114
+ res.chunked = true
115
+ io_lambda.call wr
116
+ elsif body.respond_to?(:to_path)
117
+ res.body = ::File.open(body.to_path, 'rb')
118
+ else
119
+ body.each { |part|
120
+ res.body << part
121
+ }
122
+ end
65
123
  ensure
66
124
  body.close if body.respond_to? :close
67
125
  end
data/lib/rack/handler.rb CHANGED
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rack
2
4
  # *Handlers* connect web servers with Rack.
3
5
  #
4
- # Rack includes Handlers for Mongrel, WEBrick, FastCGI, CGI, SCGI
6
+ # Rack includes Handlers for Thin, WEBrick, FastCGI, CGI, SCGI
5
7
  # and LiteSpeed.
6
8
  #
7
9
  # Handlers usually are activated by calling <tt>MyHandler.run(myapp)</tt>.
@@ -12,13 +14,50 @@ module Rack
12
14
  return unless server
13
15
  server = server.to_s
14
16
 
17
+ unless @handlers.include? server
18
+ load_error = try_require('rack/handler', server)
19
+ end
20
+
15
21
  if klass = @handlers[server]
16
- obj = Object
17
- klass.split("::").each { |x| obj = obj.const_get(x) }
18
- obj
22
+ const_get(klass)
23
+ else
24
+ const_get(server, false)
25
+ end
26
+
27
+ rescue NameError => name_error
28
+ raise load_error || name_error
29
+ end
30
+
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
52
+ # Guess.
53
+ if ENV.include?("PHP_FCGI_CHILDREN")
54
+ Rack::Handler::FastCGI
55
+ elsif ENV.include?(REQUEST_METHOD)
56
+ Rack::Handler::CGI
57
+ elsif ENV.include?("RACK_HANDLER")
58
+ self.get(ENV["RACK_HANDLER"])
19
59
  else
20
- try_require('rack/handler', server)
21
- const_get(server)
60
+ pick SERVER_NAMES
22
61
  end
23
62
  end
24
63
 
@@ -38,19 +77,18 @@ module Rack
38
77
  gsub(/[A-Z]+[^A-Z]/, '_\&').downcase
39
78
 
40
79
  require(::File.join(prefix, file))
41
- rescue LoadError
80
+ nil
81
+ rescue LoadError => error
82
+ error
42
83
  end
43
84
 
44
85
  def self.register(server, klass)
45
86
  @handlers ||= {}
46
- @handlers[server] = klass
87
+ @handlers[server.to_s] = klass.to_s
47
88
  end
48
89
 
49
90
  autoload :CGI, "rack/handler/cgi"
50
91
  autoload :FastCGI, "rack/handler/fastcgi"
51
- autoload :Mongrel, "rack/handler/mongrel"
52
- autoload :EventedMongrel, "rack/handler/evented_mongrel"
53
- autoload :SwiftipliedMongrel, "rack/handler/swiftiplied_mongrel"
54
92
  autoload :WEBrick, "rack/handler/webrick"
55
93
  autoload :LSWS, "rack/handler/lsws"
56
94
  autoload :SCGI, "rack/handler/scgi"
@@ -58,9 +96,6 @@ module Rack
58
96
 
59
97
  register 'cgi', 'Rack::Handler::CGI'
60
98
  register 'fastcgi', 'Rack::Handler::FastCGI'
61
- register 'mongrel', 'Rack::Handler::Mongrel'
62
- register 'emongrel', 'Rack::Handler::EventedMongrel'
63
- register 'smongrel', 'Rack::Handler::SwiftipliedMongrel'
64
99
  register 'webrick', 'Rack::Handler::WEBrick'
65
100
  register 'lsws', 'Rack::Handler::LSWS'
66
101
  register 'scgi', 'Rack::Handler::SCGI'
data/lib/rack/head.rb CHANGED
@@ -1,19 +1,25 @@
1
- module Rack
1
+ # frozen_string_literal: true
2
2
 
3
- class Head
4
- def initialize(app)
5
- @app = app
6
- end
3
+ module Rack
4
+ # Rack::Head returns an empty body for all HEAD requests. It leaves
5
+ # all other requests unchanged.
6
+ class Head
7
+ def initialize(app)
8
+ @app = app
9
+ end
7
10
 
8
- def call(env)
9
- status, headers, body = @app.call(env)
11
+ def call(env)
12
+ status, headers, body = @app.call(env)
10
13
 
11
- if env["REQUEST_METHOD"] == "HEAD"
12
- [status, headers, []]
13
- else
14
- [status, headers, body]
14
+ if env[REQUEST_METHOD] == HEAD
15
+ [
16
+ status, headers, Rack::BodyProxy.new([]) do
17
+ body.close if body.respond_to? :close
18
+ end
19
+ ]
20
+ else
21
+ [status, headers, body]
22
+ end
15
23
  end
16
24
  end
17
25
  end
18
-
19
- end