rack 2.0.9 → 2.1.4
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +77 -0
- data/{COPYING → MIT-LICENSE} +4 -2
- data/README.rdoc +77 -117
- data/Rakefile +25 -18
- data/SPEC +3 -4
- data/bin/rackup +1 -0
- data/example/lobster.ru +2 -0
- data/example/protectedlobster.rb +3 -1
- data/example/protectedlobster.ru +2 -0
- data/lib/rack.rb +63 -60
- data/lib/rack/auth/abstract/handler.rb +3 -1
- data/lib/rack/auth/abstract/request.rb +2 -0
- data/lib/rack/auth/basic.rb +4 -1
- data/lib/rack/auth/digest/md5.rb +9 -7
- data/lib/rack/auth/digest/nonce.rb +6 -3
- data/lib/rack/auth/digest/params.rb +4 -2
- data/lib/rack/auth/digest/request.rb +2 -0
- data/lib/rack/body_proxy.rb +3 -6
- data/lib/rack/builder.rb +39 -15
- data/lib/rack/cascade.rb +6 -5
- data/lib/rack/chunked.rb +29 -6
- data/lib/rack/common_logger.rb +9 -8
- data/lib/rack/conditional_get.rb +3 -1
- data/lib/rack/config.rb +2 -0
- data/lib/rack/content_length.rb +3 -1
- data/lib/rack/content_type.rb +3 -1
- data/lib/rack/core_ext/regexp.rb +14 -0
- data/lib/rack/deflater.rb +32 -17
- data/lib/rack/directory.rb +19 -16
- data/lib/rack/etag.rb +3 -1
- data/lib/rack/events.rb +5 -3
- data/lib/rack/file.rb +4 -173
- data/lib/rack/files.rb +178 -0
- data/lib/rack/handler.rb +7 -2
- data/lib/rack/handler/cgi.rb +3 -1
- data/lib/rack/handler/fastcgi.rb +4 -2
- data/lib/rack/handler/lsws.rb +3 -1
- data/lib/rack/handler/scgi.rb +9 -6
- data/lib/rack/handler/thin.rb +3 -1
- data/lib/rack/handler/webrick.rb +4 -2
- data/lib/rack/head.rb +2 -0
- data/lib/rack/lint.rb +14 -11
- data/lib/rack/lobster.rb +7 -5
- data/lib/rack/lock.rb +2 -0
- data/lib/rack/logger.rb +2 -0
- data/lib/rack/media_type.rb +10 -5
- data/lib/rack/method_override.rb +4 -2
- data/lib/rack/mime.rb +9 -1
- data/lib/rack/mock.rb +74 -15
- data/lib/rack/multipart.rb +5 -3
- data/lib/rack/multipart/generator.rb +6 -7
- data/lib/rack/multipart/parser.rb +51 -45
- data/lib/rack/multipart/uploaded_file.rb +2 -0
- data/lib/rack/null_logger.rb +2 -0
- data/lib/rack/query_parser.rb +51 -25
- data/lib/rack/recursive.rb +7 -5
- data/lib/rack/reloader.rb +10 -4
- data/lib/rack/request.rb +79 -26
- data/lib/rack/response.rb +71 -31
- data/lib/rack/rewindable_input.rb +4 -2
- data/lib/rack/runtime.rb +4 -2
- data/lib/rack/sendfile.rb +15 -8
- data/lib/rack/server.rb +88 -18
- data/lib/rack/session/abstract/id.rb +30 -20
- data/lib/rack/session/cookie.rb +10 -9
- data/lib/rack/session/memcache.rb +4 -93
- data/lib/rack/session/pool.rb +4 -2
- data/lib/rack/show_exceptions.rb +15 -9
- data/lib/rack/show_status.rb +4 -2
- data/lib/rack/static.rb +15 -10
- data/lib/rack/tempfile_reaper.rb +2 -0
- data/lib/rack/urlmap.rb +11 -2
- data/lib/rack/utils.rb +59 -72
- data/rack.gemspec +17 -7
- metadata +33 -175
- data/HISTORY.md +0 -505
- data/test/builder/an_underscore_app.rb +0 -5
- data/test/builder/anything.rb +0 -5
- data/test/builder/comment.ru +0 -4
- data/test/builder/end.ru +0 -5
- data/test/builder/line.ru +0 -1
- data/test/builder/options.ru +0 -2
- data/test/cgi/assets/folder/test.js +0 -1
- data/test/cgi/assets/fonts/font.eot +0 -1
- data/test/cgi/assets/images/image.png +0 -1
- data/test/cgi/assets/index.html +0 -1
- data/test/cgi/assets/javascripts/app.js +0 -1
- data/test/cgi/assets/stylesheets/app.css +0 -1
- data/test/cgi/lighttpd.conf +0 -26
- data/test/cgi/rackup_stub.rb +0 -6
- data/test/cgi/sample_rackup.ru +0 -5
- data/test/cgi/test +0 -9
- data/test/cgi/test+directory/test+file +0 -1
- data/test/cgi/test.fcgi +0 -9
- data/test/cgi/test.gz +0 -0
- data/test/cgi/test.ru +0 -5
- data/test/gemloader.rb +0 -10
- data/test/helper.rb +0 -34
- data/test/multipart/bad_robots +0 -259
- data/test/multipart/binary +0 -0
- data/test/multipart/content_type_and_no_filename +0 -6
- data/test/multipart/empty +0 -10
- data/test/multipart/fail_16384_nofile +0 -814
- data/test/multipart/file1.txt +0 -1
- data/test/multipart/filename_and_modification_param +0 -7
- data/test/multipart/filename_and_no_name +0 -6
- data/test/multipart/filename_with_encoded_words +0 -7
- data/test/multipart/filename_with_escaped_quotes +0 -6
- data/test/multipart/filename_with_escaped_quotes_and_modification_param +0 -7
- data/test/multipart/filename_with_null_byte +0 -7
- data/test/multipart/filename_with_percent_escaped_quotes +0 -6
- data/test/multipart/filename_with_single_quote +0 -7
- data/test/multipart/filename_with_unescaped_percentages +0 -6
- data/test/multipart/filename_with_unescaped_percentages2 +0 -6
- data/test/multipart/filename_with_unescaped_percentages3 +0 -6
- data/test/multipart/filename_with_unescaped_quotes +0 -6
- data/test/multipart/ie +0 -6
- data/test/multipart/invalid_character +0 -6
- data/test/multipart/mixed_files +0 -21
- data/test/multipart/nested +0 -10
- data/test/multipart/none +0 -9
- data/test/multipart/quoted +0 -15
- data/test/multipart/rack-logo.png +0 -0
- data/test/multipart/semicolon +0 -6
- data/test/multipart/text +0 -15
- data/test/multipart/three_files_three_fields +0 -31
- data/test/multipart/unity3d_wwwform +0 -11
- data/test/multipart/webkit +0 -32
- data/test/rackup/config.ru +0 -31
- data/test/registering_handler/rack/handler/registering_myself.rb +0 -8
- data/test/spec_auth_basic.rb +0 -89
- data/test/spec_auth_digest.rb +0 -260
- data/test/spec_body_proxy.rb +0 -85
- data/test/spec_builder.rb +0 -233
- data/test/spec_cascade.rb +0 -63
- data/test/spec_cgi.rb +0 -84
- data/test/spec_chunked.rb +0 -103
- data/test/spec_common_logger.rb +0 -95
- data/test/spec_conditional_get.rb +0 -103
- data/test/spec_config.rb +0 -23
- data/test/spec_content_length.rb +0 -86
- data/test/spec_content_type.rb +0 -46
- data/test/spec_deflater.rb +0 -375
- data/test/spec_directory.rb +0 -148
- data/test/spec_etag.rb +0 -108
- data/test/spec_events.rb +0 -133
- data/test/spec_fastcgi.rb +0 -85
- data/test/spec_file.rb +0 -264
- data/test/spec_handler.rb +0 -57
- data/test/spec_head.rb +0 -46
- data/test/spec_lint.rb +0 -515
- data/test/spec_lobster.rb +0 -59
- data/test/spec_lock.rb +0 -204
- data/test/spec_logger.rb +0 -24
- data/test/spec_media_type.rb +0 -42
- data/test/spec_method_override.rb +0 -110
- data/test/spec_mime.rb +0 -51
- data/test/spec_mock.rb +0 -359
- data/test/spec_multipart.rb +0 -722
- data/test/spec_null_logger.rb +0 -21
- data/test/spec_recursive.rb +0 -75
- data/test/spec_request.rb +0 -1407
- data/test/spec_response.rb +0 -528
- data/test/spec_rewindable_input.rb +0 -128
- data/test/spec_runtime.rb +0 -50
- data/test/spec_sendfile.rb +0 -125
- data/test/spec_server.rb +0 -193
- data/test/spec_session_abstract_id.rb +0 -31
- data/test/spec_session_abstract_session_hash.rb +0 -45
- data/test/spec_session_cookie.rb +0 -442
- data/test/spec_session_memcache.rb +0 -357
- data/test/spec_session_persisted_secure_secure_session_hash.rb +0 -73
- data/test/spec_session_pool.rb +0 -247
- data/test/spec_show_exceptions.rb +0 -93
- data/test/spec_show_status.rb +0 -104
- data/test/spec_static.rb +0 -184
- data/test/spec_tempfile_reaper.rb +0 -64
- data/test/spec_thin.rb +0 -96
- data/test/spec_urlmap.rb +0 -237
- data/test/spec_utils.rb +0 -742
- data/test/spec_version.rb +0 -11
- data/test/spec_webrick.rb +0 -206
- data/test/static/another/index.html +0 -1
- data/test/static/foo.html +0 -1
- data/test/static/index.html +0 -1
- data/test/testrequest.rb +0 -78
- data/test/unregistered_handler/rack/handler/unregistered.rb +0 -7
- data/test/unregistered_handler/rack/handler/unregistered_long_one.rb +0 -7
data/SPEC
CHANGED
@@ -60,9 +60,8 @@ below.
|
|
60
60
|
the presence or absence of the
|
61
61
|
appropriate HTTP header in the
|
62
62
|
request. See
|
63
|
-
|
64
|
-
|
65
|
-
specific behavior.
|
63
|
+
{RFC3875 section 4.1.18}[https://tools.ietf.org/html/rfc3875#section-4.1.18]
|
64
|
+
for specific behavior.
|
66
65
|
In addition to this, the Rack environment must include these
|
67
66
|
Rack-specific variables:
|
68
67
|
<tt>rack.version</tt>:: The Array representing this version of Rack
|
@@ -226,9 +225,9 @@ This is an HTTP status. When parsed as integer (+to_i+), it must be
|
|
226
225
|
greater than or equal to 100.
|
227
226
|
=== The Headers
|
228
227
|
The header must respond to +each+, and yield values of key and value.
|
228
|
+
The header keys must be Strings.
|
229
229
|
Special headers starting "rack." are for communicating with the
|
230
230
|
server, and must not be sent back to the client.
|
231
|
-
The header keys must be Strings.
|
232
231
|
The header must not contain a +Status+ key.
|
233
232
|
The header must conform to RFC7230 token specification, i.e. cannot
|
234
233
|
contain non-printable ASCII, DQUOTE or "(),/:;<=>?@[\]{}".
|
data/bin/rackup
CHANGED
data/example/lobster.ru
CHANGED
data/example/protectedlobster.rb
CHANGED
@@ -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 :
|
16
|
+
Rack::Server.start app: pretty_protected_lobster, Port: 9292
|
data/example/protectedlobster.ru
CHANGED
data/lib/rack.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
|
-
#
|
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
|
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.
|
23
|
+
RELEASE = "2.1.4"
|
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'
|
29
|
-
HTTP_VERSION = 'HTTP_VERSION'
|
30
|
-
HTTPS = 'HTTPS'
|
31
|
-
PATH_INFO = 'PATH_INFO'
|
32
|
-
REQUEST_METHOD = 'REQUEST_METHOD'
|
33
|
-
REQUEST_PATH = 'REQUEST_PATH'
|
34
|
-
SCRIPT_NAME = 'SCRIPT_NAME'
|
35
|
-
QUERY_STRING = 'QUERY_STRING'
|
36
|
-
SERVER_PROTOCOL = 'SERVER_PROTOCOL'
|
37
|
-
SERVER_NAME = 'SERVER_NAME'
|
38
|
-
SERVER_ADDR = 'SERVER_ADDR'
|
39
|
-
SERVER_PORT = 'SERVER_PORT'
|
40
|
-
CACHE_CONTROL = 'Cache-Control'
|
41
|
-
CONTENT_LENGTH = 'Content-Length'
|
42
|
-
CONTENT_TYPE = 'Content-Type'
|
43
|
-
SET_COOKIE = 'Set-Cookie'
|
44
|
-
TRANSFER_ENCODING = 'Transfer-Encoding'
|
45
|
-
HTTP_COOKIE = 'HTTP_COOKIE'
|
46
|
-
ETAG = 'ETag'
|
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'
|
50
|
-
POST = 'POST'
|
51
|
-
PUT = 'PUT'
|
52
|
-
PATCH = 'PATCH'
|
53
|
-
DELETE = 'DELETE'
|
54
|
-
HEAD = 'HEAD'
|
55
|
-
OPTIONS = 'OPTIONS'
|
56
|
-
LINK = 'LINK'
|
57
|
-
UNLINK = 'UNLINK'
|
58
|
-
TRACE = 'TRACE'
|
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'
|
62
|
-
RACK_TEMPFILES = 'rack.tempfiles'
|
63
|
-
RACK_ERRORS = 'rack.errors'
|
64
|
-
RACK_LOGGER = 'rack.logger'
|
65
|
-
RACK_INPUT = 'rack.input'
|
66
|
-
RACK_SESSION = 'rack.session'
|
67
|
-
RACK_SESSION_OPTIONS = 'rack.session.options'
|
68
|
-
RACK_SHOWSTATUS_DETAIL = 'rack.showstatus.detail'
|
69
|
-
RACK_MULTITHREAD = 'rack.multithread'
|
70
|
-
RACK_MULTIPROCESS = 'rack.multiprocess'
|
71
|
-
RACK_RUNONCE = 'rack.run_once'
|
72
|
-
RACK_URL_SCHEME = 'rack.url_scheme'
|
73
|
-
RACK_HIJACK = 'rack.hijack'
|
74
|
-
RACK_IS_HIJACK = 'rack.hijack?'
|
75
|
-
RACK_HIJACK_IO = 'rack.hijack_io'
|
76
|
-
RACK_RECURSIVE_INCLUDE = 'rack.recursive.include'
|
77
|
-
RACK_MULTIPART_BUFFER_SIZE = 'rack.multipart.buffer_size'
|
78
|
-
RACK_MULTIPART_TEMPFILE_FACTORY = 'rack.multipart.tempfile_factory'
|
79
|
-
RACK_REQUEST_FORM_INPUT = 'rack.request.form_input'
|
80
|
-
RACK_REQUEST_FORM_HASH = 'rack.request.form_hash'
|
81
|
-
RACK_REQUEST_FORM_VARS = 'rack.request.form_vars'
|
82
|
-
RACK_REQUEST_COOKIE_HASH = 'rack.request.cookie_hash'
|
83
|
-
RACK_REQUEST_COOKIE_STRING = 'rack.request.cookie_string'
|
84
|
-
RACK_REQUEST_QUERY_HASH = 'rack.request.query_hash'
|
85
|
-
RACK_REQUEST_QUERY_STRING = 'rack.request.query_string'
|
86
|
-
RACK_METHODOVERRIDE_ORIGINAL_METHOD = 'rack.methodoverride.original_method'
|
87
|
-
RACK_SESSION_UNPACKED_COOKIE_DATA = 'rack.session.unpacked_cookie_data'
|
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
|
|
data/lib/rack/auth/basic.rb
CHANGED
@@ -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 ||=
|
51
|
+
@credentials ||= Base64.decode64(params).split(':', 2)
|
49
52
|
end
|
50
53
|
|
51
54
|
def username
|
data/lib/rack/auth/digest/md5.rb
CHANGED
@@ -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(:
|
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'
|
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
|
111
|
+
H "#{secret}:#{data}"
|
110
112
|
end
|
111
113
|
|
112
114
|
def A1(auth, password)
|
113
|
-
|
115
|
+
"#{auth.username}:#{auth.realm}:#{password}"
|
114
116
|
end
|
115
117
|
|
116
118
|
def A2(auth)
|
117
|
-
|
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
|
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(*
|
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
|
-
|
32
|
+
Base64.encode64("#{@timestamp} #{digest}").strip
|
30
33
|
end
|
31
34
|
|
32
35
|
def digest
|
33
|
-
::Digest::MD5.hexdigest(
|
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}
|
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
|
-
'"'
|
48
|
+
'"' + str.gsub(/[\\\"]/o, "\\\1") + '"'
|
47
49
|
end
|
48
50
|
|
49
51
|
end
|
data/lib/rack/body_proxy.rb
CHANGED
@@ -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
|
data/lib/rack/builder.rb
CHANGED
@@ -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
|
-
|
34
|
-
|
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,10 +97,11 @@ 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
|
100
|
+
@use << proc { |app| generate_map(app, mapping) }
|
85
101
|
end
|
86
102
|
@use << proc { |app| middleware.new(app, *args, &block) }
|
87
103
|
end
|
104
|
+
ruby2_keywords(:use) if respond_to?(:ruby2_keywords, true)
|
88
105
|
|
89
106
|
# Takes an argument that is an object that responds to #call and returns a Rack response.
|
90
107
|
# The simplest form of this is a lambda object:
|
@@ -113,7 +130,7 @@ module Rack
|
|
113
130
|
#
|
114
131
|
# use SomeMiddleware
|
115
132
|
# run MyApp
|
116
|
-
def warmup(prc=nil, &block)
|
133
|
+
def warmup(prc = nil, &block)
|
117
134
|
@warmup = prc || block
|
118
135
|
end
|
119
136
|
|
@@ -141,10 +158,17 @@ module Rack
|
|
141
158
|
@map[path] = block
|
142
159
|
end
|
143
160
|
|
161
|
+
# Freeze the app (set using run) and all middleware instances when building the application
|
162
|
+
# in to_app.
|
163
|
+
def freeze_app
|
164
|
+
@freeze_app = true
|
165
|
+
end
|
166
|
+
|
144
167
|
def to_app
|
145
168
|
app = @map ? generate_map(@run, @map) : @run
|
146
169
|
fail "missing run or map statement" unless app
|
147
|
-
app
|
170
|
+
app.freeze if @freeze_app
|
171
|
+
app = @use.reverse.inject(app) { |a, e| e[a].tap { |x| x.freeze if @freeze_app } }
|
148
172
|
@warmup.call(app) if @warmup
|
149
173
|
app
|
150
174
|
end
|
@@ -156,8 +180,8 @@ module Rack
|
|
156
180
|
private
|
157
181
|
|
158
182
|
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 }
|
183
|
+
mapped = default_app ? { '/' => default_app } : {}
|
184
|
+
mapping.each { |r, b| mapped[r] = self.class.new(default_app, &b).to_app }
|
161
185
|
URLMap.new(mapped)
|
162
186
|
end
|
163
187
|
end
|