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
data/contrib/rdoc.css ADDED
@@ -0,0 +1,412 @@
1
+ /* Forked from the Darkfish templates rdoc.css file, much hacked, probably
2
+ * imperfect */
3
+
4
+ html { max-width: 960px; margin: 0 auto; }
5
+ body {
6
+ font: 14px "Helvetica Neue", Helvetica, Tahoma, sans-serif;
7
+ }
8
+ body.file-popup {
9
+ font-size: 90%;
10
+ margin-left: 0;
11
+ }
12
+
13
+ h1 {
14
+ color: #4183C4;
15
+ }
16
+
17
+ :link,
18
+ :visited {
19
+ color: #4183C4;
20
+ text-decoration: none;
21
+ }
22
+ :link:hover,
23
+ :visited:hover {
24
+ border-bottom: 1px dotted #4183C4;
25
+ }
26
+
27
+ pre, pre.description {
28
+ font: 12px Monaco,"Courier New","DejaVu Sans Mono","Bitstream Vera Sans Mono",monospace;
29
+ padding: 1em;
30
+ overflow: auto;
31
+ line-height: 1.4;
32
+ }
33
+
34
+ /* @group Generic Classes */
35
+
36
+ .initially-hidden {
37
+ display: none;
38
+ }
39
+
40
+ #search-field {
41
+ width: 98%;
42
+ }
43
+
44
+ .missing-docs {
45
+ font-size: 120%;
46
+ background: white url(images/wrench_orange.png) no-repeat 4px center;
47
+ color: #ccc;
48
+ line-height: 2em;
49
+ border: 1px solid #d00;
50
+ opacity: 1;
51
+ text-indent: 24px;
52
+ letter-spacing: 3px;
53
+ font-weight: bold;
54
+ -webkit-border-radius: 5px;
55
+ -moz-border-radius: 5px;
56
+ }
57
+
58
+ .target-section {
59
+ border: 2px solid #dcce90;
60
+ border-left-width: 8px;
61
+ background: #fff3c2;
62
+ }
63
+
64
+ /* @end */
65
+
66
+ /* @group Index Page, Standalone file pages */
67
+ .indexpage ul {
68
+ line-height: 160%;
69
+ list-style: none;
70
+ }
71
+ .indexpage ul :link,
72
+ .indexpage ul :visited {
73
+ font-size: 16px;
74
+ }
75
+
76
+ .indexpage li {
77
+ padding-left: 20px;
78
+ }
79
+
80
+ .indexpage ul > li {
81
+ background: url(images/bullet_black.png) no-repeat left 4px;
82
+ }
83
+ .indexpage li.method {
84
+ background: url(images/plugin.png) no-repeat left 4px;
85
+ }
86
+ .indexpage li.module {
87
+ background: url(images/package.png) no-repeat left 4px;
88
+ }
89
+ .indexpage li.class {
90
+ background: url(images/ruby.png) no-repeat left 4px;
91
+ }
92
+ .indexpage li.file {
93
+ background: url(images/page_white_text.png) no-repeat left 4px;
94
+ }
95
+ .indexpage li li {
96
+ background: url(images/tag_blue.png) no-repeat left 4px;
97
+ }
98
+ .indexpage li .toc-toggle {
99
+ width: 16px;
100
+ height: 16px;
101
+ background: url(images/add.png) no-repeat;
102
+ }
103
+
104
+ .indexpage li .toc-toggle.open {
105
+ background: url(images/delete.png) no-repeat;
106
+ }
107
+
108
+ /* @end */
109
+
110
+ /* @group Top-Level Structure */
111
+
112
+ .project-section, #file-metadata, #class-metadata {
113
+ display: block;
114
+ background: #f5f5f5;
115
+ margin-bottom: 1em;
116
+ padding: 0.5em;
117
+ }
118
+ .project-section h3, #file-metadata h3, #class-metadata h3 {
119
+ margin: 0;
120
+ }
121
+
122
+ #metadata {
123
+ float: left;
124
+ width: 280px;
125
+ }
126
+
127
+ #documentation {
128
+ margin: 2em 1em 2em 300px;
129
+ }
130
+
131
+ #validator-badges {
132
+ clear: both;
133
+ margin: 1em 1em 2em;
134
+ font-size: smaller;
135
+ }
136
+
137
+ /* @end */
138
+
139
+ /* @group Metadata Section */
140
+
141
+ #metadata ul,
142
+ #metadata dl,
143
+ #metadata p {
144
+ padding: 0px;
145
+ list-style: none;
146
+ }
147
+
148
+ dl.svninfo {
149
+ color: #666;
150
+ margin: 0;
151
+ }
152
+ dl.svninfo dt {
153
+ font-weight: bold;
154
+ }
155
+
156
+ ul.link-list li {
157
+ white-space: nowrap;
158
+ }
159
+ ul.link-list .type {
160
+ font-size: 8px;
161
+ text-transform: uppercase;
162
+ color: white;
163
+ background: #969696;
164
+ }
165
+
166
+ /* @end */
167
+
168
+ /* @group Documentation Section */
169
+
170
+ .note-list {
171
+ margin: 8px 0;
172
+ }
173
+
174
+ .label-list {
175
+ margin: 8px 1.5em;
176
+ border: 1px solid #ccc;
177
+ }
178
+ .description .label-list {
179
+ font-size: 14px;
180
+ }
181
+
182
+ .note-list dt {
183
+ font-weight: bold;
184
+ }
185
+ .note-list dd {
186
+ }
187
+
188
+ .label-list dt {
189
+ font-weight: bold;
190
+ background: #ddd;
191
+ }
192
+ .label-list dd {
193
+ }
194
+ .label-list dd + dt,
195
+ .note-list dd + dt {
196
+ margin-top: 0.7em;
197
+ }
198
+
199
+ #documentation .section {
200
+ font-size: 90%;
201
+ }
202
+
203
+ #documentation h2.section-header {
204
+ color: #333;
205
+ font-size: 175%;
206
+ }
207
+
208
+ .documentation-section-title {
209
+ position: relative;
210
+ }
211
+ .documentation-section-title .section-click-top {
212
+ position: absolute;
213
+ top: 6px;
214
+ right: 12px;
215
+ font-size: 10px;
216
+ visibility: hidden;
217
+ }
218
+
219
+ .documentation-section-title:hover .section-click-top {
220
+ visibility: visible;
221
+ }
222
+
223
+ #documentation h3.section-header {
224
+ color: #333;
225
+ font-size: 150%;
226
+ }
227
+
228
+ #constants-list > dl,
229
+ #attributes-list > dl {
230
+ margin: 1em 0 2em;
231
+ border: 0;
232
+ }
233
+ #constants-list > dl dt,
234
+ #attributes-list > dl dt {
235
+ font-weight: bold;
236
+ font-family: Monaco, "Andale Mono";
237
+ background: inherit;
238
+ }
239
+ #constants-list > dl dt a,
240
+ #attributes-list > dl dt a {
241
+ color: inherit;
242
+ }
243
+ #constants-list > dl dd,
244
+ #attributes-list > dl dd {
245
+ margin: 0 0 1em 0;
246
+ color: #666;
247
+ }
248
+
249
+ .documentation-section h2 {
250
+ position: relative;
251
+ }
252
+
253
+ .documentation-section h2 a {
254
+ position: absolute;
255
+ top: 8px;
256
+ right: 10px;
257
+ font-size: 12px;
258
+ color: #9b9877;
259
+ visibility: hidden;
260
+ }
261
+
262
+ .documentation-section h2:hover a {
263
+ visibility: visible;
264
+ }
265
+
266
+ /* @group Method Details */
267
+
268
+ #documentation .method-source-code {
269
+ display: none;
270
+ }
271
+
272
+ #documentation .method-detail {
273
+ margin: 0.2em 0.2em;
274
+ padding: 0.5em;
275
+ }
276
+ #documentation .method-detail:hover {
277
+ background-color: #f5f5f5;
278
+ }
279
+ #documentation .method-heading {
280
+ cursor: pointer;
281
+ position: relative;
282
+ font-size: 125%;
283
+ line-height: 125%;
284
+ font-weight: bold;
285
+ color: #333;
286
+ background: url(images/brick.png) no-repeat left bottom;
287
+ padding-left: 20px;
288
+ }
289
+ #documentation .method-heading :link,
290
+ #documentation .method-heading :visited {
291
+ color: inherit;
292
+ }
293
+ #documentation .method-click-advice {
294
+ position: absolute;
295
+ right: 5px;
296
+ font-size: 10px;
297
+ color: #aaa;
298
+ visibility: hidden;
299
+ background: url(images/zoom.png) no-repeat right 5px;
300
+ padding-right: 20px;
301
+ overflow: show;
302
+ }
303
+ #documentation .method-heading:hover .method-click-advice {
304
+ visibility: visible;
305
+ }
306
+
307
+ #documentation .method-alias .method-heading {
308
+ color: #666;
309
+ background: url(images/brick_link.png) no-repeat left bottom;
310
+ }
311
+
312
+ #documentation .method-description,
313
+ #documentation .aliases {
314
+ margin: 0 20px;
315
+ color: #666;
316
+ }
317
+
318
+ #documentation .method-description p,
319
+ #documentation .aliases p {
320
+ line-height: 1.2em;
321
+ }
322
+
323
+ #documentation .aliases {
324
+ font-style: italic;
325
+ cursor: default;
326
+ }
327
+ #documentation .method-description p {
328
+ margin-bottom: 0.5em;
329
+ }
330
+ #documentation .method-description ul {
331
+ margin-left: 1.5em;
332
+ }
333
+
334
+ #documentation .attribute-method-heading {
335
+ background: url(images/tag_green.png) no-repeat left bottom;
336
+ }
337
+ #documentation #attribute-method-details .method-detail:hover {
338
+ background-color: transparent;
339
+ cursor: default;
340
+ }
341
+ #documentation .attribute-access-type {
342
+ font-size: 60%;
343
+ text-transform: uppercase;
344
+ vertical-align: super;
345
+ }
346
+
347
+ .method-section .method-source-code {
348
+ background: white;
349
+ }
350
+
351
+ /* @group Source Code */
352
+
353
+ .ruby-constant .ruby-keyword .ruby-ivar .ruby-operator .ruby-identifier
354
+ .ruby-node .ruby-comment .ruby-regexp .ruby-value {
355
+ background: transparent;
356
+ }
357
+
358
+ /* Thanks GitHub!!! */
359
+ .ruby-constant { color: #458; font-weight: bold; }
360
+ .ruby-keyword { color: black; font-weight: bold; }
361
+ .ruby-ivar { color: teal; }
362
+ .ruby-operator { color: #000; }
363
+ .ruby-identifier { color: black; }
364
+ .ruby-node { color: red; }
365
+ .ruby-comment { color: #998; font-weight: bold; }
366
+ .ruby-regexp { color: #009926; }
367
+ .ruby-value { color: #099; }
368
+ .ruby-string { color: red; }
369
+
370
+ /* @group search results */
371
+
372
+ #search-section .section-header {
373
+ margin: 0;
374
+ padding: 0;
375
+ }
376
+
377
+ #search-results {
378
+ width: 100%;
379
+ list-style: none;
380
+ margin: 0;
381
+ padding: 0;
382
+ }
383
+
384
+ #search-results h1 {
385
+ font-size: 1em;
386
+ font-weight: normal;
387
+ text-shadow: none;
388
+ }
389
+
390
+ #search-results .current {
391
+ background: #eee;
392
+ }
393
+
394
+ #search-results li {
395
+ list-style: none;
396
+ line-height: 1em;
397
+ padding: 0.5em;
398
+ border-bottom: 1px solid black;
399
+ }
400
+
401
+ #search-results .search-namespace {
402
+ font-weight: bold;
403
+ }
404
+
405
+ #search-results li em {
406
+ background: yellow;
407
+ font-style: normal;
408
+ }
409
+
410
+ #search-results pre {
411
+ margin: 0.5em;
412
+ }
data/example/lobster.ru CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rack/lobster'
2
4
 
3
5
  use Rack::ShowExceptions
@@ -1,14 +1,16 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rack'
2
4
  require 'rack/lobster'
3
5
 
4
6
  lobster = Rack::Lobster.new
5
7
 
6
8
  protected_lobster = Rack::Auth::Basic.new(lobster) do |username, password|
7
- 'secret' == password
9
+ Rack::Utils.secure_compare('secret', password)
8
10
  end
9
11
 
10
12
  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::Handler::WEBrick.run pretty_protected_lobster, :Port => 9292
16
+ Rack::Server.start app: pretty_protected_lobster, Port: 9292
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rack/lobster'
2
4
 
3
5
  use Rack::ShowExceptions
4
6
  use Rack::Auth::Basic, "Lobster 2.0" do |username, password|
5
- 'secret' == password
7
+ Rack::Utils.secure_compare('secret', password)
6
8
  end
7
9
 
8
10
  run Rack::Lobster.new
@@ -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
 
@@ -17,8 +19,8 @@ module Rack
17
19
 
18
20
  def unauthorized(www_authenticate = challenge)
19
21
  return [ 401,
20
- { 'Content-Type' => 'text/plain',
21
- 'Content-Length' => '0',
22
+ { CONTENT_TYPE => 'text/plain',
23
+ CONTENT_LENGTH => '0',
22
24
  'WWW-Authenticate' => www_authenticate.to_s },
23
25
  []
24
26
  ]
@@ -26,8 +28,8 @@ module Rack
26
28
 
27
29
  def bad_request
28
30
  return [ 400,
29
- { 'Content-Type' => 'text/plain',
30
- 'Content-Length' => '0' },
31
+ { CONTENT_TYPE => 'text/plain',
32
+ CONTENT_LENGTH => '0' },
31
33
  []
32
34
  ]
33
35
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rack
2
4
  module Auth
3
5
  class AbstractRequest
@@ -6,8 +8,16 @@ module Rack
6
8
  @env = env
7
9
  end
8
10
 
11
+ def request
12
+ @request ||= Request.new(@env)
13
+ end
14
+
9
15
  def provided?
10
- !authorization_key.nil?
16
+ !authorization_key.nil? && valid?
17
+ end
18
+
19
+ def valid?
20
+ !@env[authorization_key].nil?
11
21
  end
12
22
 
13
23
  def parts
@@ -15,7 +25,7 @@ module Rack
15
25
  end
16
26
 
17
27
  def scheme
18
- @scheme ||= parts.first.downcase.to_sym
28
+ @scheme ||= parts.first && parts.first.downcase
19
29
  end
20
30
 
21
31
  def params
@@ -1,5 +1,7 @@
1
- require 'rack/auth/abstract/handler'
2
- require 'rack/auth/abstract/request'
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'abstract/handler'
4
+ require_relative 'abstract/request'
3
5
 
4
6
  module Rack
5
7
  module Auth
@@ -41,11 +43,11 @@ module Rack
41
43
 
42
44
  class Request < Auth::AbstractRequest
43
45
  def basic?
44
- :basic == scheme
46
+ "basic" == scheme && credentials.length == 2
45
47
  end
46
48
 
47
49
  def credentials
48
- @credentials ||= params.unpack("m*").first.split(/:/, 2)
50
+ @credentials ||= params.unpack("m").first.split(':', 2)
49
51
  end
50
52
 
51
53
  def username
@@ -1,7 +1,9 @@
1
- require 'rack/auth/abstract/handler'
2
- require 'rack/auth/digest/request'
3
- require 'rack/auth/digest/params'
4
- require 'rack/auth/digest/nonce'
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../abstract/handler'
4
+ require_relative 'request'
5
+ require_relative 'params'
6
+ require_relative 'nonce'
5
7
  require 'digest/md5'
6
8
 
7
9
  module Rack
@@ -21,9 +23,13 @@ module Rack
21
23
 
22
24
  attr_writer :passwords_hashed
23
25
 
24
- def initialize(*args)
25
- super
26
+ def initialize(app, realm = nil, opaque = nil, &authenticator)
26
27
  @passwords_hashed = nil
28
+ if opaque.nil? and realm.respond_to? :values_at
29
+ realm, opaque, @passwords_hashed = realm.values_at :realm, :opaque, :passwords_hashed
30
+ end
31
+ super(app, realm, &authenticator)
32
+ @opaque = opaque
27
33
  end
28
34
 
29
35
  def passwords_hashed?
@@ -43,7 +49,7 @@ module Rack
43
49
 
44
50
  if valid?(auth)
45
51
  if auth.nonce.stale?
46
- return unauthorized(challenge(:stale => true))
52
+ return unauthorized(challenge(stale: true))
47
53
  else
48
54
  env['REMOTE_USER'] = auth.username
49
55
 
@@ -57,7 +63,7 @@ module Rack
57
63
 
58
64
  private
59
65
 
60
- QOP = 'auth'.freeze
66
+ QOP = 'auth'
61
67
 
62
68
  def params(hash = {})
63
69
  Params.new do |params|
@@ -91,7 +97,8 @@ module Rack
91
97
  end
92
98
 
93
99
  def valid_digest?(auth)
94
- digest(auth, @authenticator.call(auth.username)) == auth.response
100
+ pw = @authenticator.call(auth.username)
101
+ pw && Rack::Utils.secure_compare(digest(auth, pw), auth.response)
95
102
  end
96
103
 
97
104
  def md5(data)
@@ -101,21 +108,21 @@ module Rack
101
108
  alias :H :md5
102
109
 
103
110
  def KD(secret, data)
104
- H([secret, data] * ':')
111
+ H "#{secret}:#{data}"
105
112
  end
106
113
 
107
114
  def A1(auth, password)
108
- [ auth.username, auth.realm, password ] * ':'
115
+ "#{auth.username}:#{auth.realm}:#{password}"
109
116
  end
110
117
 
111
118
  def A2(auth)
112
- [ auth.method, auth.uri ] * ':'
119
+ "#{auth.method}:#{auth.uri}"
113
120
  end
114
121
 
115
122
  def digest(auth, password)
116
123
  password_hash = passwords_hashed? ? password : H(A1(auth, password))
117
124
 
118
- 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)}"
119
126
  end
120
127
 
121
128
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'digest/md5'
2
4
 
3
5
  module Rack
@@ -18,7 +20,7 @@ module Rack
18
20
  end
19
21
 
20
22
  def self.parse(string)
21
- new(*string.unpack("m*").first.split(' ', 2))
23
+ new(*string.unpack("m").first.split(' ', 2))
22
24
  end
23
25
 
24
26
  def initialize(timestamp = Time.now, given_digest = nil)
@@ -26,11 +28,11 @@ module Rack
26
28
  end
27
29
 
28
30
  def to_s
29
- [([ @timestamp, digest ] * ' ')].pack("m*").strip
31
+ ["#{@timestamp} #{digest}"].pack("m").strip
30
32
  end
31
33
 
32
34
  def digest
33
- ::Digest::MD5.hexdigest([ @timestamp, self.class.private_key ] * ':')
35
+ ::Digest::MD5.hexdigest("#{@timestamp}:#{self.class.private_key}")
34
36
  end
35
37
 
36
38
  def valid?
@@ -38,7 +40,7 @@ module Rack
38
40
  end
39
41
 
40
42
  def stale?
41
- !self.class.time_limit.nil? && (@timestamp - Time.now.to_i) < self.class.time_limit
43
+ !self.class.time_limit.nil? && (Time.now.to_i - @timestamp) > self.class.time_limit
42
44
  end
43
45
 
44
46
  def fresh?