rack 2.0.4 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rack might be problematic. Click here for more details.

Files changed (187) hide show
  1. checksums.yaml +4 -4
  2. data/{HISTORY.md → CHANGELOG.md} +220 -155
  3. data/{COPYING → MIT-LICENSE} +4 -2
  4. data/README.rdoc +77 -119
  5. data/Rakefile +25 -18
  6. data/SPEC +3 -4
  7. data/bin/rackup +1 -0
  8. data/example/lobster.ru +2 -0
  9. data/example/protectedlobster.rb +3 -1
  10. data/example/protectedlobster.ru +2 -0
  11. data/lib/rack.rb +63 -60
  12. data/lib/rack/auth/abstract/handler.rb +3 -1
  13. data/lib/rack/auth/abstract/request.rb +2 -0
  14. data/lib/rack/auth/basic.rb +4 -1
  15. data/lib/rack/auth/digest/md5.rb +9 -7
  16. data/lib/rack/auth/digest/nonce.rb +6 -3
  17. data/lib/rack/auth/digest/params.rb +4 -2
  18. data/lib/rack/auth/digest/request.rb +2 -0
  19. data/lib/rack/body_proxy.rb +3 -6
  20. data/lib/rack/builder.rb +38 -15
  21. data/lib/rack/cascade.rb +6 -5
  22. data/lib/rack/chunked.rb +29 -6
  23. data/lib/rack/common_logger.rb +9 -8
  24. data/lib/rack/conditional_get.rb +3 -1
  25. data/lib/rack/config.rb +2 -0
  26. data/lib/rack/content_length.rb +3 -1
  27. data/lib/rack/content_type.rb +3 -1
  28. data/lib/rack/core_ext/regexp.rb +14 -0
  29. data/lib/rack/deflater.rb +28 -17
  30. data/lib/rack/directory.rb +17 -14
  31. data/lib/rack/etag.rb +3 -1
  32. data/lib/rack/events.rb +5 -3
  33. data/lib/rack/file.rb +5 -173
  34. data/lib/rack/files.rb +178 -0
  35. data/lib/rack/handler.rb +7 -2
  36. data/lib/rack/handler/cgi.rb +3 -1
  37. data/lib/rack/handler/fastcgi.rb +4 -2
  38. data/lib/rack/handler/lsws.rb +3 -1
  39. data/lib/rack/handler/scgi.rb +9 -6
  40. data/lib/rack/handler/thin.rb +3 -1
  41. data/lib/rack/handler/webrick.rb +4 -2
  42. data/lib/rack/head.rb +2 -0
  43. data/lib/rack/lint.rb +14 -11
  44. data/lib/rack/lobster.rb +7 -5
  45. data/lib/rack/lock.rb +2 -0
  46. data/lib/rack/logger.rb +2 -0
  47. data/lib/rack/media_type.rb +10 -5
  48. data/lib/rack/method_override.rb +9 -3
  49. data/lib/rack/mime.rb +9 -1
  50. data/lib/rack/mock.rb +74 -15
  51. data/lib/rack/multipart.rb +5 -3
  52. data/lib/rack/multipart/generator.rb +6 -7
  53. data/lib/rack/multipart/parser.rb +54 -51
  54. data/lib/rack/multipart/uploaded_file.rb +2 -0
  55. data/lib/rack/null_logger.rb +2 -0
  56. data/lib/rack/query_parser.rb +51 -25
  57. data/lib/rack/recursive.rb +7 -5
  58. data/lib/rack/reloader.rb +10 -4
  59. data/lib/rack/request.rb +89 -23
  60. data/lib/rack/response.rb +71 -31
  61. data/lib/rack/rewindable_input.rb +4 -2
  62. data/lib/rack/runtime.rb +4 -2
  63. data/lib/rack/sendfile.rb +15 -8
  64. data/lib/rack/server.rb +88 -16
  65. data/lib/rack/session/abstract/id.rb +104 -21
  66. data/lib/rack/session/cookie.rb +21 -11
  67. data/lib/rack/session/memcache.rb +4 -87
  68. data/lib/rack/session/pool.rb +17 -8
  69. data/lib/rack/show_exceptions.rb +16 -10
  70. data/lib/rack/show_status.rb +4 -2
  71. data/lib/rack/static.rb +15 -10
  72. data/lib/rack/tempfile_reaper.rb +2 -0
  73. data/lib/rack/urlmap.rb +11 -2
  74. data/lib/rack/utils.rb +55 -70
  75. data/rack.gemspec +19 -9
  76. metadata +32 -173
  77. data/test/builder/an_underscore_app.rb +0 -5
  78. data/test/builder/anything.rb +0 -5
  79. data/test/builder/comment.ru +0 -4
  80. data/test/builder/end.ru +0 -5
  81. data/test/builder/line.ru +0 -1
  82. data/test/builder/options.ru +0 -2
  83. data/test/cgi/assets/folder/test.js +0 -1
  84. data/test/cgi/assets/fonts/font.eot +0 -1
  85. data/test/cgi/assets/images/image.png +0 -1
  86. data/test/cgi/assets/index.html +0 -1
  87. data/test/cgi/assets/javascripts/app.js +0 -1
  88. data/test/cgi/assets/stylesheets/app.css +0 -1
  89. data/test/cgi/lighttpd.conf +0 -26
  90. data/test/cgi/rackup_stub.rb +0 -6
  91. data/test/cgi/sample_rackup.ru +0 -5
  92. data/test/cgi/test +0 -9
  93. data/test/cgi/test+directory/test+file +0 -1
  94. data/test/cgi/test.fcgi +0 -9
  95. data/test/cgi/test.gz +0 -0
  96. data/test/cgi/test.ru +0 -5
  97. data/test/gemloader.rb +0 -10
  98. data/test/helper.rb +0 -34
  99. data/test/multipart/bad_robots +0 -259
  100. data/test/multipart/binary +0 -0
  101. data/test/multipart/content_type_and_no_filename +0 -6
  102. data/test/multipart/empty +0 -10
  103. data/test/multipart/fail_16384_nofile +0 -814
  104. data/test/multipart/file1.txt +0 -1
  105. data/test/multipart/filename_and_modification_param +0 -7
  106. data/test/multipart/filename_and_no_name +0 -6
  107. data/test/multipart/filename_with_encoded_words +0 -7
  108. data/test/multipart/filename_with_escaped_quotes +0 -6
  109. data/test/multipart/filename_with_escaped_quotes_and_modification_param +0 -7
  110. data/test/multipart/filename_with_null_byte +0 -7
  111. data/test/multipart/filename_with_percent_escaped_quotes +0 -6
  112. data/test/multipart/filename_with_single_quote +0 -7
  113. data/test/multipart/filename_with_unescaped_percentages +0 -6
  114. data/test/multipart/filename_with_unescaped_percentages2 +0 -6
  115. data/test/multipart/filename_with_unescaped_percentages3 +0 -6
  116. data/test/multipart/filename_with_unescaped_quotes +0 -6
  117. data/test/multipart/ie +0 -6
  118. data/test/multipart/invalid_character +0 -6
  119. data/test/multipart/mixed_files +0 -21
  120. data/test/multipart/nested +0 -10
  121. data/test/multipart/none +0 -9
  122. data/test/multipart/quoted +0 -15
  123. data/test/multipart/rack-logo.png +0 -0
  124. data/test/multipart/semicolon +0 -6
  125. data/test/multipart/text +0 -15
  126. data/test/multipart/three_files_three_fields +0 -31
  127. data/test/multipart/unity3d_wwwform +0 -11
  128. data/test/multipart/webkit +0 -32
  129. data/test/rackup/config.ru +0 -31
  130. data/test/registering_handler/rack/handler/registering_myself.rb +0 -8
  131. data/test/spec_auth_basic.rb +0 -89
  132. data/test/spec_auth_digest.rb +0 -260
  133. data/test/spec_body_proxy.rb +0 -85
  134. data/test/spec_builder.rb +0 -233
  135. data/test/spec_cascade.rb +0 -63
  136. data/test/spec_cgi.rb +0 -84
  137. data/test/spec_chunked.rb +0 -103
  138. data/test/spec_common_logger.rb +0 -95
  139. data/test/spec_conditional_get.rb +0 -103
  140. data/test/spec_config.rb +0 -23
  141. data/test/spec_content_length.rb +0 -86
  142. data/test/spec_content_type.rb +0 -46
  143. data/test/spec_deflater.rb +0 -375
  144. data/test/spec_directory.rb +0 -148
  145. data/test/spec_etag.rb +0 -108
  146. data/test/spec_events.rb +0 -133
  147. data/test/spec_fastcgi.rb +0 -85
  148. data/test/spec_file.rb +0 -264
  149. data/test/spec_handler.rb +0 -57
  150. data/test/spec_head.rb +0 -46
  151. data/test/spec_lint.rb +0 -515
  152. data/test/spec_lobster.rb +0 -59
  153. data/test/spec_lock.rb +0 -204
  154. data/test/spec_logger.rb +0 -24
  155. data/test/spec_media_type.rb +0 -42
  156. data/test/spec_method_override.rb +0 -96
  157. data/test/spec_mime.rb +0 -51
  158. data/test/spec_mock.rb +0 -359
  159. data/test/spec_multipart.rb +0 -722
  160. data/test/spec_null_logger.rb +0 -21
  161. data/test/spec_recursive.rb +0 -75
  162. data/test/spec_request.rb +0 -1393
  163. data/test/spec_response.rb +0 -510
  164. data/test/spec_rewindable_input.rb +0 -128
  165. data/test/spec_runtime.rb +0 -50
  166. data/test/spec_sendfile.rb +0 -125
  167. data/test/spec_server.rb +0 -193
  168. data/test/spec_session_abstract_id.rb +0 -31
  169. data/test/spec_session_abstract_session_hash.rb +0 -45
  170. data/test/spec_session_cookie.rb +0 -442
  171. data/test/spec_session_memcache.rb +0 -320
  172. data/test/spec_session_pool.rb +0 -210
  173. data/test/spec_show_exceptions.rb +0 -80
  174. data/test/spec_show_status.rb +0 -104
  175. data/test/spec_static.rb +0 -184
  176. data/test/spec_tempfile_reaper.rb +0 -64
  177. data/test/spec_thin.rb +0 -96
  178. data/test/spec_urlmap.rb +0 -237
  179. data/test/spec_utils.rb +0 -742
  180. data/test/spec_version.rb +0 -11
  181. data/test/spec_webrick.rb +0 -206
  182. data/test/static/another/index.html +0 -1
  183. data/test/static/foo.html +0 -1
  184. data/test/static/index.html +0 -1
  185. data/test/testrequest.rb +0 -78
  186. data/test/unregistered_handler/rack/handler/unregistered.rb +0 -7
  187. data/test/unregistered_handler/rack/handler/unregistered_long_one.rb +0 -7
data/bin/rackup CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require "rack"
4
5
  Rack::Server.start
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rack/lobster'
2
4
 
3
5
  use Rack::ShowExceptions
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rack'
2
4
  require 'rack/lobster'
3
5
 
@@ -11,4 +13,4 @@ protected_lobster.realm = 'Lobster 2.0'
11
13
 
12
14
  pretty_protected_lobster = Rack::ShowStatus.new(Rack::ShowExceptions.new(protected_lobster))
13
15
 
14
- Rack::Server.start :app => pretty_protected_lobster, :Port => 9292
16
+ Rack::Server.start app: pretty_protected_lobster, Port: 9292
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rack/lobster'
2
4
 
3
5
  use Rack::ShowExceptions
@@ -1,7 +1,9 @@
1
- # Copyright (C) 2007, 2008, 2009, 2010 Christian Neukirchen <purl.org/net/chneukirchen>
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (C) 2007-2019 Leah Neukirchen <http://leahneukirchen.org/infopage.html>
2
4
  #
3
5
  # Rack is freely distributable under the terms of an MIT-style license.
4
- # See COPYING or http://www.opensource.org/licenses/mit-license.php.
6
+ # See MIT-LICENSE or https://opensource.org/licenses/MIT.
5
7
 
6
8
  # The Rack main module, serving as a namespace for all core Rack
7
9
  # modules and classes.
@@ -11,80 +13,80 @@
11
13
 
12
14
  module Rack
13
15
  # The Rack protocol version number implemented.
14
- VERSION = [1,3]
16
+ VERSION = [1, 3]
15
17
 
16
18
  # Return the Rack protocol version as a dotted string.
17
19
  def self.version
18
20
  VERSION.join(".")
19
21
  end
20
22
 
21
- RELEASE = "2.0.4"
23
+ RELEASE = "2.1.0"
22
24
 
23
25
  # Return the Rack release as a dotted string.
24
26
  def self.release
25
27
  RELEASE
26
28
  end
27
29
 
28
- HTTP_HOST = 'HTTP_HOST'.freeze
29
- HTTP_VERSION = 'HTTP_VERSION'.freeze
30
- HTTPS = 'HTTPS'.freeze
31
- PATH_INFO = 'PATH_INFO'.freeze
32
- REQUEST_METHOD = 'REQUEST_METHOD'.freeze
33
- REQUEST_PATH = 'REQUEST_PATH'.freeze
34
- SCRIPT_NAME = 'SCRIPT_NAME'.freeze
35
- QUERY_STRING = 'QUERY_STRING'.freeze
36
- SERVER_PROTOCOL = 'SERVER_PROTOCOL'.freeze
37
- SERVER_NAME = 'SERVER_NAME'.freeze
38
- SERVER_ADDR = 'SERVER_ADDR'.freeze
39
- SERVER_PORT = 'SERVER_PORT'.freeze
40
- CACHE_CONTROL = 'Cache-Control'.freeze
41
- CONTENT_LENGTH = 'Content-Length'.freeze
42
- CONTENT_TYPE = 'Content-Type'.freeze
43
- SET_COOKIE = 'Set-Cookie'.freeze
44
- TRANSFER_ENCODING = 'Transfer-Encoding'.freeze
45
- HTTP_COOKIE = 'HTTP_COOKIE'.freeze
46
- ETAG = 'ETag'.freeze
30
+ HTTP_HOST = 'HTTP_HOST'
31
+ HTTP_VERSION = 'HTTP_VERSION'
32
+ HTTPS = 'HTTPS'
33
+ PATH_INFO = 'PATH_INFO'
34
+ REQUEST_METHOD = 'REQUEST_METHOD'
35
+ REQUEST_PATH = 'REQUEST_PATH'
36
+ SCRIPT_NAME = 'SCRIPT_NAME'
37
+ QUERY_STRING = 'QUERY_STRING'
38
+ SERVER_PROTOCOL = 'SERVER_PROTOCOL'
39
+ SERVER_NAME = 'SERVER_NAME'
40
+ SERVER_ADDR = 'SERVER_ADDR'
41
+ SERVER_PORT = 'SERVER_PORT'
42
+ CACHE_CONTROL = 'Cache-Control'
43
+ CONTENT_LENGTH = 'Content-Length'
44
+ CONTENT_TYPE = 'Content-Type'
45
+ SET_COOKIE = 'Set-Cookie'
46
+ TRANSFER_ENCODING = 'Transfer-Encoding'
47
+ HTTP_COOKIE = 'HTTP_COOKIE'
48
+ ETAG = 'ETag'
47
49
 
48
50
  # HTTP method verbs
49
- GET = 'GET'.freeze
50
- POST = 'POST'.freeze
51
- PUT = 'PUT'.freeze
52
- PATCH = 'PATCH'.freeze
53
- DELETE = 'DELETE'.freeze
54
- HEAD = 'HEAD'.freeze
55
- OPTIONS = 'OPTIONS'.freeze
56
- LINK = 'LINK'.freeze
57
- UNLINK = 'UNLINK'.freeze
58
- TRACE = 'TRACE'.freeze
51
+ GET = 'GET'
52
+ POST = 'POST'
53
+ PUT = 'PUT'
54
+ PATCH = 'PATCH'
55
+ DELETE = 'DELETE'
56
+ HEAD = 'HEAD'
57
+ OPTIONS = 'OPTIONS'
58
+ LINK = 'LINK'
59
+ UNLINK = 'UNLINK'
60
+ TRACE = 'TRACE'
59
61
 
60
62
  # Rack environment variables
61
- RACK_VERSION = 'rack.version'.freeze
62
- RACK_TEMPFILES = 'rack.tempfiles'.freeze
63
- RACK_ERRORS = 'rack.errors'.freeze
64
- RACK_LOGGER = 'rack.logger'.freeze
65
- RACK_INPUT = 'rack.input'.freeze
66
- RACK_SESSION = 'rack.session'.freeze
67
- RACK_SESSION_OPTIONS = 'rack.session.options'.freeze
68
- RACK_SHOWSTATUS_DETAIL = 'rack.showstatus.detail'.freeze
69
- RACK_MULTITHREAD = 'rack.multithread'.freeze
70
- RACK_MULTIPROCESS = 'rack.multiprocess'.freeze
71
- RACK_RUNONCE = 'rack.run_once'.freeze
72
- RACK_URL_SCHEME = 'rack.url_scheme'.freeze
73
- RACK_HIJACK = 'rack.hijack'.freeze
74
- RACK_IS_HIJACK = 'rack.hijack?'.freeze
75
- RACK_HIJACK_IO = 'rack.hijack_io'.freeze
76
- RACK_RECURSIVE_INCLUDE = 'rack.recursive.include'.freeze
77
- RACK_MULTIPART_BUFFER_SIZE = 'rack.multipart.buffer_size'.freeze
78
- RACK_MULTIPART_TEMPFILE_FACTORY = 'rack.multipart.tempfile_factory'.freeze
79
- RACK_REQUEST_FORM_INPUT = 'rack.request.form_input'.freeze
80
- RACK_REQUEST_FORM_HASH = 'rack.request.form_hash'.freeze
81
- RACK_REQUEST_FORM_VARS = 'rack.request.form_vars'.freeze
82
- RACK_REQUEST_COOKIE_HASH = 'rack.request.cookie_hash'.freeze
83
- RACK_REQUEST_COOKIE_STRING = 'rack.request.cookie_string'.freeze
84
- RACK_REQUEST_QUERY_HASH = 'rack.request.query_hash'.freeze
85
- RACK_REQUEST_QUERY_STRING = 'rack.request.query_string'.freeze
86
- RACK_METHODOVERRIDE_ORIGINAL_METHOD = 'rack.methodoverride.original_method'.freeze
87
- RACK_SESSION_UNPACKED_COOKIE_DATA = 'rack.session.unpacked_cookie_data'.freeze
63
+ RACK_VERSION = 'rack.version'
64
+ RACK_TEMPFILES = 'rack.tempfiles'
65
+ RACK_ERRORS = 'rack.errors'
66
+ RACK_LOGGER = 'rack.logger'
67
+ RACK_INPUT = 'rack.input'
68
+ RACK_SESSION = 'rack.session'
69
+ RACK_SESSION_OPTIONS = 'rack.session.options'
70
+ RACK_SHOWSTATUS_DETAIL = 'rack.showstatus.detail'
71
+ RACK_MULTITHREAD = 'rack.multithread'
72
+ RACK_MULTIPROCESS = 'rack.multiprocess'
73
+ RACK_RUNONCE = 'rack.run_once'
74
+ RACK_URL_SCHEME = 'rack.url_scheme'
75
+ RACK_HIJACK = 'rack.hijack'
76
+ RACK_IS_HIJACK = 'rack.hijack?'
77
+ RACK_HIJACK_IO = 'rack.hijack_io'
78
+ RACK_RECURSIVE_INCLUDE = 'rack.recursive.include'
79
+ RACK_MULTIPART_BUFFER_SIZE = 'rack.multipart.buffer_size'
80
+ RACK_MULTIPART_TEMPFILE_FACTORY = 'rack.multipart.tempfile_factory'
81
+ RACK_REQUEST_FORM_INPUT = 'rack.request.form_input'
82
+ RACK_REQUEST_FORM_HASH = 'rack.request.form_hash'
83
+ RACK_REQUEST_FORM_VARS = 'rack.request.form_vars'
84
+ RACK_REQUEST_COOKIE_HASH = 'rack.request.cookie_hash'
85
+ RACK_REQUEST_COOKIE_STRING = 'rack.request.cookie_string'
86
+ RACK_REQUEST_QUERY_HASH = 'rack.request.query_hash'
87
+ RACK_REQUEST_QUERY_STRING = 'rack.request.query_string'
88
+ RACK_METHODOVERRIDE_ORIGINAL_METHOD = 'rack.methodoverride.original_method'
89
+ RACK_SESSION_UNPACKED_COOKIE_DATA = 'rack.session.unpacked_cookie_data'
88
90
 
89
91
  autoload :Builder, "rack/builder"
90
92
  autoload :BodyProxy, "rack/body_proxy"
@@ -97,6 +99,7 @@ module Rack
97
99
  autoload :ContentType, "rack/content_type"
98
100
  autoload :ETag, "rack/etag"
99
101
  autoload :File, "rack/file"
102
+ autoload :Files, "rack/files"
100
103
  autoload :Deflater, "rack/deflater"
101
104
  autoload :Directory, "rack/directory"
102
105
  autoload :ForwardRequest, "rack/recursive"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rack
2
4
  module Auth
3
5
  # Rack::Auth::AbstractHandler implements common authentication functionality.
@@ -8,7 +10,7 @@ module Rack
8
10
 
9
11
  attr_accessor :realm
10
12
 
11
- def initialize(app, realm=nil, &authenticator)
13
+ def initialize(app, realm = nil, &authenticator)
12
14
  @app, @realm, @authenticator = app, realm, authenticator
13
15
  end
14
16
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rack/request'
2
4
 
3
5
  module Rack
@@ -1,5 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rack/auth/abstract/handler'
2
4
  require 'rack/auth/abstract/request'
5
+ require 'base64'
3
6
 
4
7
  module Rack
5
8
  module Auth
@@ -45,7 +48,7 @@ module Rack
45
48
  end
46
49
 
47
50
  def credentials
48
- @credentials ||= params.unpack("m*").first.split(/:/, 2)
51
+ @credentials ||= Base64.decode64(params).split(':', 2)
49
52
  end
50
53
 
51
54
  def username
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rack/auth/abstract/handler'
2
4
  require 'rack/auth/digest/request'
3
5
  require 'rack/auth/digest/params'
@@ -21,7 +23,7 @@ module Rack
21
23
 
22
24
  attr_writer :passwords_hashed
23
25
 
24
- def initialize(app, realm=nil, opaque=nil, &authenticator)
26
+ def initialize(app, realm = nil, opaque = nil, &authenticator)
25
27
  @passwords_hashed = nil
26
28
  if opaque.nil? and realm.respond_to? :values_at
27
29
  realm, opaque, @passwords_hashed = realm.values_at :realm, :opaque, :passwords_hashed
@@ -47,7 +49,7 @@ module Rack
47
49
 
48
50
  if valid?(auth)
49
51
  if auth.nonce.stale?
50
- return unauthorized(challenge(:stale => true))
52
+ return unauthorized(challenge(stale: true))
51
53
  else
52
54
  env['REMOTE_USER'] = auth.username
53
55
 
@@ -61,7 +63,7 @@ module Rack
61
63
 
62
64
  private
63
65
 
64
- QOP = 'auth'.freeze
66
+ QOP = 'auth'
65
67
 
66
68
  def params(hash = {})
67
69
  Params.new do |params|
@@ -106,21 +108,21 @@ module Rack
106
108
  alias :H :md5
107
109
 
108
110
  def KD(secret, data)
109
- H([secret, data] * ':')
111
+ H "#{secret}:#{data}"
110
112
  end
111
113
 
112
114
  def A1(auth, password)
113
- [ auth.username, auth.realm, password ] * ':'
115
+ "#{auth.username}:#{auth.realm}:#{password}"
114
116
  end
115
117
 
116
118
  def A2(auth)
117
- [ auth.method, auth.uri ] * ':'
119
+ "#{auth.method}:#{auth.uri}"
118
120
  end
119
121
 
120
122
  def digest(auth, password)
121
123
  password_hash = passwords_hashed? ? password : H(A1(auth, password))
122
124
 
123
- KD(password_hash, [ auth.nonce, auth.nc, auth.cnonce, QOP, H(A2(auth)) ] * ':')
125
+ KD password_hash, "#{auth.nonce}:#{auth.nc}:#{auth.cnonce}:#{QOP}:#{H A2(auth)}"
124
126
  end
125
127
 
126
128
  end
@@ -1,4 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'digest/md5'
4
+ require 'base64'
2
5
 
3
6
  module Rack
4
7
  module Auth
@@ -18,7 +21,7 @@ module Rack
18
21
  end
19
22
 
20
23
  def self.parse(string)
21
- new(*string.unpack("m*").first.split(' ', 2))
24
+ new(*Base64.decode64(string).split(' ', 2))
22
25
  end
23
26
 
24
27
  def initialize(timestamp = Time.now, given_digest = nil)
@@ -26,11 +29,11 @@ module Rack
26
29
  end
27
30
 
28
31
  def to_s
29
- [([ @timestamp, digest ] * ' ')].pack("m*").strip
32
+ Base64.encode64("#{@timestamp} #{digest}").strip
30
33
  end
31
34
 
32
35
  def digest
33
- ::Digest::MD5.hexdigest([ @timestamp, self.class.private_key ] * ':')
36
+ ::Digest::MD5.hexdigest("#{@timestamp}:#{self.class.private_key}")
34
37
  end
35
38
 
36
39
  def valid?
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rack
2
4
  module Auth
3
5
  module Digest
@@ -38,12 +40,12 @@ module Rack
38
40
 
39
41
  def to_s
40
42
  map do |k, v|
41
- "#{k}=" << (UNQUOTED.include?(k) ? v.to_s : quote(v))
43
+ "#{k}=#{(UNQUOTED.include?(k) ? v.to_s : quote(v))}"
42
44
  end.join(', ')
43
45
  end
44
46
 
45
47
  def quote(str) # From WEBrick::HTTPUtils
46
- '"' << str.gsub(/[\\\"]/o, "\\\1") << '"'
48
+ '"' + str.gsub(/[\\\"]/o, "\\\1") + '"'
47
49
  end
48
50
 
49
51
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rack/auth/abstract/request'
2
4
  require 'rack/auth/digest/params'
3
5
  require 'rack/auth/digest/nonce'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rack
2
4
  class BodyProxy
3
5
  def initialize(body, &block)
@@ -6,11 +8,7 @@ module Rack
6
8
  @closed = false
7
9
  end
8
10
 
9
- def respond_to?(method_name, include_all=false)
10
- case method_name
11
- when :to_ary, 'to_ary'
12
- return false
13
- end
11
+ def respond_to?(method_name, include_all = false)
14
12
  super or @body.respond_to?(method_name, include_all)
15
13
  end
16
14
 
@@ -37,7 +35,6 @@ module Rack
37
35
  end
38
36
 
39
37
  def method_missing(method_name, *args, &block)
40
- super if :to_ary == method_name
41
38
  @body.__send__(method_name, *args, &block)
42
39
  end
43
40
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rack
2
4
  # Rack::Builder implements a small DSL to iteratively construct Rack
3
5
  # applications.
@@ -29,29 +31,43 @@ module Rack
29
31
  # You can use +map+ to construct a Rack::URLMap in a convenient way.
30
32
 
31
33
  class Builder
34
+
35
+ # https://stackoverflow.com/questions/2223882/whats-the-difference-between-utf-8-and-utf-8-without-bom
36
+ UTF_8_BOM = '\xef\xbb\xbf'
37
+
32
38
  def self.parse_file(config, opts = Server::Options.new)
33
- options = {}
34
- if config =~ /\.ru$/
35
- cfgfile = ::File.read(config)
36
- if cfgfile[/^#\\(.*)/] && opts
37
- options = opts.parse! $1.split(/\s+/)
38
- end
39
- cfgfile.sub!(/^__END__\n.*\Z/m, '')
40
- app = new_from_string cfgfile, config
39
+ if config.end_with?('.ru')
40
+ return self.load_file(config, opts)
41
41
  else
42
42
  require config
43
43
  app = Object.const_get(::File.basename(config, '.rb').split('_').map(&:capitalize).join(''))
44
+ return app, {}
45
+ end
46
+ end
47
+
48
+ def self.load_file(path, opts = Server::Options.new)
49
+ options = {}
50
+
51
+ cfgfile = ::File.read(path)
52
+ cfgfile.slice!(/\A#{UTF_8_BOM}/) if cfgfile.encoding == Encoding::UTF_8
53
+
54
+ if cfgfile[/^#\\(.*)/] && opts
55
+ options = opts.parse! $1.split(/\s+/)
44
56
  end
57
+
58
+ cfgfile.sub!(/^__END__\n.*\Z/m, '')
59
+ app = new_from_string cfgfile, path
60
+
45
61
  return app, options
46
62
  end
47
63
 
48
- def self.new_from_string(builder_script, file="(rackup)")
64
+ def self.new_from_string(builder_script, file = "(rackup)")
49
65
  eval "Rack::Builder.new {\n" + builder_script + "\n}.to_app",
50
66
  TOPLEVEL_BINDING, file, 0
51
67
  end
52
68
 
53
69
  def initialize(default_app = nil, &block)
54
- @use, @map, @run, @warmup = [], nil, default_app, nil
70
+ @use, @map, @run, @warmup, @freeze_app = [], nil, default_app, nil, false
55
71
  instance_eval(&block) if block_given?
56
72
  end
57
73
 
@@ -81,7 +97,7 @@ module Rack
81
97
  def use(middleware, *args, &block)
82
98
  if @map
83
99
  mapping, @map = @map, nil
84
- @use << proc { |app| generate_map app, mapping }
100
+ @use << proc { |app| generate_map(app, mapping) }
85
101
  end
86
102
  @use << proc { |app| middleware.new(app, *args, &block) }
87
103
  end
@@ -113,7 +129,7 @@ module Rack
113
129
  #
114
130
  # use SomeMiddleware
115
131
  # run MyApp
116
- def warmup(prc=nil, &block)
132
+ def warmup(prc = nil, &block)
117
133
  @warmup = prc || block
118
134
  end
119
135
 
@@ -141,10 +157,17 @@ module Rack
141
157
  @map[path] = block
142
158
  end
143
159
 
160
+ # Freeze the app (set using run) and all middleware instances when building the application
161
+ # in to_app.
162
+ def freeze_app
163
+ @freeze_app = true
164
+ end
165
+
144
166
  def to_app
145
167
  app = @map ? generate_map(@run, @map) : @run
146
168
  fail "missing run or map statement" unless app
147
- app = @use.reverse.inject(app) { |a,e| e[a] }
169
+ app.freeze if @freeze_app
170
+ app = @use.reverse.inject(app) { |a, e| e[a].tap { |x| x.freeze if @freeze_app } }
148
171
  @warmup.call(app) if @warmup
149
172
  app
150
173
  end
@@ -156,8 +179,8 @@ module Rack
156
179
  private
157
180
 
158
181
  def generate_map(default_app, mapping)
159
- mapped = default_app ? {'/' => default_app} : {}
160
- mapping.each { |r,b| mapped[r] = self.class.new(default_app, &b).to_app }
182
+ mapped = default_app ? { '/' => default_app } : {}
183
+ mapping.each { |r, b| mapped[r] = self.class.new(default_app, &b).to_app }
161
184
  URLMap.new(mapped)
162
185
  end
163
186
  end