rack 2.2.18 → 3.2.3
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +561 -75
- data/CONTRIBUTING.md +63 -55
- data/MIT-LICENSE +1 -1
- data/README.md +384 -0
- data/SPEC.rdoc +243 -277
- data/lib/rack/auth/abstract/handler.rb +3 -1
- data/lib/rack/auth/abstract/request.rb +5 -1
- data/lib/rack/auth/basic.rb +1 -3
- data/lib/rack/bad_request.rb +8 -0
- data/lib/rack/body_proxy.rb +21 -3
- data/lib/rack/builder.rb +108 -69
- data/lib/rack/cascade.rb +2 -3
- data/lib/rack/common_logger.rb +22 -17
- data/lib/rack/conditional_get.rb +20 -16
- data/lib/rack/constants.rb +68 -0
- data/lib/rack/content_length.rb +12 -16
- data/lib/rack/content_type.rb +8 -5
- data/lib/rack/deflater.rb +40 -26
- data/lib/rack/directory.rb +9 -3
- data/lib/rack/etag.rb +17 -23
- data/lib/rack/events.rb +25 -6
- data/lib/rack/files.rb +15 -17
- data/lib/rack/head.rb +8 -8
- data/lib/rack/headers.rb +238 -0
- data/lib/rack/lint.rb +817 -648
- data/lib/rack/lock.rb +2 -5
- data/lib/rack/media_type.rb +6 -7
- data/lib/rack/method_override.rb +5 -1
- data/lib/rack/mime.rb +14 -5
- data/lib/rack/mock.rb +1 -300
- data/lib/rack/mock_request.rb +161 -0
- data/lib/rack/mock_response.rb +147 -0
- data/lib/rack/multipart/generator.rb +7 -5
- data/lib/rack/multipart/parser.rb +291 -95
- data/lib/rack/multipart/uploaded_file.rb +45 -4
- data/lib/rack/multipart.rb +53 -40
- data/lib/rack/null_logger.rb +9 -0
- data/lib/rack/query_parser.rb +118 -121
- data/lib/rack/recursive.rb +2 -0
- data/lib/rack/reloader.rb +0 -2
- data/lib/rack/request.rb +272 -141
- data/lib/rack/response.rb +151 -66
- data/lib/rack/rewindable_input.rb +27 -5
- data/lib/rack/runtime.rb +7 -6
- data/lib/rack/sendfile.rb +68 -33
- data/lib/rack/show_exceptions.rb +25 -6
- data/lib/rack/show_status.rb +17 -9
- data/lib/rack/static.rb +8 -8
- data/lib/rack/tempfile_reaper.rb +15 -4
- data/lib/rack/urlmap.rb +3 -1
- data/lib/rack/utils.rb +228 -238
- data/lib/rack/version.rb +3 -15
- data/lib/rack.rb +13 -90
- metadata +14 -40
- data/README.rdoc +0 -347
- data/Rakefile +0 -130
- data/bin/rackup +0 -5
- data/contrib/rack.png +0 -0
- data/contrib/rack.svg +0 -150
- data/contrib/rack_logo.svg +0 -164
- data/contrib/rdoc.css +0 -412
- data/example/lobster.ru +0 -6
- data/example/protectedlobster.rb +0 -16
- data/example/protectedlobster.ru +0 -10
- data/lib/rack/auth/digest/md5.rb +0 -131
- data/lib/rack/auth/digest/nonce.rb +0 -53
- data/lib/rack/auth/digest/params.rb +0 -54
- data/lib/rack/auth/digest/request.rb +0 -43
- data/lib/rack/chunked.rb +0 -117
- data/lib/rack/core_ext/regexp.rb +0 -14
- data/lib/rack/file.rb +0 -7
- data/lib/rack/handler/cgi.rb +0 -59
- data/lib/rack/handler/fastcgi.rb +0 -100
- data/lib/rack/handler/lsws.rb +0 -61
- data/lib/rack/handler/scgi.rb +0 -71
- data/lib/rack/handler/thin.rb +0 -34
- data/lib/rack/handler/webrick.rb +0 -129
- data/lib/rack/handler.rb +0 -104
- data/lib/rack/lobster.rb +0 -70
- data/lib/rack/logger.rb +0 -20
- data/lib/rack/server.rb +0 -466
- data/lib/rack/session/abstract/id.rb +0 -523
- data/lib/rack/session/cookie.rb +0 -203
- data/lib/rack/session/memcache.rb +0 -10
- data/lib/rack/session/pool.rb +0 -90
- data/rack.gemspec +0 -46
@@ -0,0 +1,147 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'time'
|
4
|
+
|
5
|
+
require_relative 'response'
|
6
|
+
|
7
|
+
module Rack
|
8
|
+
# Rack::MockResponse provides useful helpers for testing your apps.
|
9
|
+
# Usually, you don't create the MockResponse on your own, but use
|
10
|
+
# MockRequest.
|
11
|
+
|
12
|
+
class MockResponse < Rack::Response
|
13
|
+
class Cookie
|
14
|
+
attr_reader :name, :value, :path, :domain, :expires, :secure
|
15
|
+
|
16
|
+
def initialize(args)
|
17
|
+
@name = args["name"]
|
18
|
+
@value = args["value"]
|
19
|
+
@path = args["path"]
|
20
|
+
@domain = args["domain"]
|
21
|
+
@expires = args["expires"]
|
22
|
+
@secure = args["secure"]
|
23
|
+
end
|
24
|
+
|
25
|
+
def method_missing(method_name, *args, &block)
|
26
|
+
@value.send(method_name, *args, &block)
|
27
|
+
end
|
28
|
+
# :nocov:
|
29
|
+
ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
|
30
|
+
# :nocov:
|
31
|
+
|
32
|
+
def respond_to_missing?(method_name, include_all = false)
|
33
|
+
@value.respond_to?(method_name, include_all) || super
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class << self
|
38
|
+
alias [] new
|
39
|
+
end
|
40
|
+
|
41
|
+
# Headers
|
42
|
+
attr_reader :original_headers, :cookies
|
43
|
+
|
44
|
+
# Errors
|
45
|
+
attr_accessor :errors
|
46
|
+
|
47
|
+
def initialize(status, headers, body, errors = nil)
|
48
|
+
@original_headers = headers
|
49
|
+
|
50
|
+
if errors
|
51
|
+
@errors = errors.string if errors.respond_to?(:string)
|
52
|
+
else
|
53
|
+
@errors = ""
|
54
|
+
end
|
55
|
+
|
56
|
+
super(body, status, headers)
|
57
|
+
|
58
|
+
@cookies = parse_cookies_from_header
|
59
|
+
buffered_body!
|
60
|
+
end
|
61
|
+
|
62
|
+
def =~(other)
|
63
|
+
body =~ other
|
64
|
+
end
|
65
|
+
|
66
|
+
def match(other)
|
67
|
+
body.match other
|
68
|
+
end
|
69
|
+
|
70
|
+
def body
|
71
|
+
return @buffered_body if defined?(@buffered_body)
|
72
|
+
|
73
|
+
# FIXME: apparently users of MockResponse expect the return value of
|
74
|
+
# MockResponse#body to be a string. However, the real response object
|
75
|
+
# returns the body as a list.
|
76
|
+
#
|
77
|
+
# See spec_showstatus.rb:
|
78
|
+
#
|
79
|
+
# should "not replace existing messages" do
|
80
|
+
# ...
|
81
|
+
# res.body.should == "foo!"
|
82
|
+
# end
|
83
|
+
buffer = @buffered_body = String.new
|
84
|
+
|
85
|
+
@body.each do |chunk|
|
86
|
+
buffer << chunk
|
87
|
+
end
|
88
|
+
|
89
|
+
return buffer
|
90
|
+
end
|
91
|
+
|
92
|
+
def empty?
|
93
|
+
[201, 204, 304].include? status
|
94
|
+
end
|
95
|
+
|
96
|
+
def cookie(name)
|
97
|
+
cookies.fetch(name, nil)
|
98
|
+
end
|
99
|
+
|
100
|
+
private
|
101
|
+
|
102
|
+
def parse_cookies_from_header
|
103
|
+
cookies = Hash.new
|
104
|
+
set_cookie_header = headers['set-cookie']
|
105
|
+
if set_cookie_header && !set_cookie_header.empty?
|
106
|
+
Array(set_cookie_header).each do |cookie|
|
107
|
+
cookie_name, cookie_filling = cookie.split('=', 2)
|
108
|
+
cookie_attributes = identify_cookie_attributes cookie_filling
|
109
|
+
parsed_cookie = Cookie.new(
|
110
|
+
'name' => cookie_name.strip,
|
111
|
+
'value' => cookie_attributes.fetch('value'),
|
112
|
+
'path' => cookie_attributes.fetch('path', nil),
|
113
|
+
'domain' => cookie_attributes.fetch('domain', nil),
|
114
|
+
'expires' => cookie_attributes.fetch('expires', nil),
|
115
|
+
'secure' => cookie_attributes.fetch('secure', false)
|
116
|
+
)
|
117
|
+
cookies.store(cookie_name, parsed_cookie)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
cookies
|
121
|
+
end
|
122
|
+
|
123
|
+
def identify_cookie_attributes(cookie_filling)
|
124
|
+
cookie_bits = cookie_filling.split(';')
|
125
|
+
cookie_attributes = Hash.new
|
126
|
+
cookie_attributes.store('value', Array(cookie_bits[0].strip))
|
127
|
+
cookie_bits.drop(1).each do |bit|
|
128
|
+
if bit.include? '='
|
129
|
+
cookie_attribute, attribute_value = bit.split('=', 2)
|
130
|
+
cookie_attributes.store(cookie_attribute.strip.downcase, attribute_value.strip)
|
131
|
+
end
|
132
|
+
if bit.include? 'secure'
|
133
|
+
cookie_attributes.store('secure', true)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
if cookie_attributes.key? 'max-age'
|
138
|
+
cookie_attributes.store('expires', Time.now + cookie_attributes['max-age'].to_i)
|
139
|
+
elsif cookie_attributes.key? 'expires'
|
140
|
+
cookie_attributes.store('expires', Time.httpdate(cookie_attributes['expires']))
|
141
|
+
end
|
142
|
+
|
143
|
+
cookie_attributes
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
147
|
+
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative 'uploaded_file'
|
4
|
+
|
3
5
|
module Rack
|
4
6
|
module Multipart
|
5
7
|
class Generator
|
@@ -74,12 +76,12 @@ module Rack
|
|
74
76
|
|
75
77
|
def content_for_tempfile(io, file, name)
|
76
78
|
length = ::File.stat(file.path).size if file.path
|
77
|
-
filename = "; filename=\"#{Utils.
|
79
|
+
filename = "; filename=\"#{Utils.escape_path(file.original_filename)}\""
|
78
80
|
<<-EOF
|
79
81
|
--#{MULTIPART_BOUNDARY}\r
|
80
|
-
|
81
|
-
|
82
|
-
#{"
|
82
|
+
content-disposition: form-data; name="#{name}"#{filename}\r
|
83
|
+
content-type: #{file.content_type}\r
|
84
|
+
#{"content-length: #{length}\r\n" if length}\r
|
83
85
|
#{io.read}\r
|
84
86
|
EOF
|
85
87
|
end
|
@@ -87,7 +89,7 @@ EOF
|
|
87
89
|
def content_for_other(file, name)
|
88
90
|
<<-EOF
|
89
91
|
--#{MULTIPART_BOUNDARY}\r
|
90
|
-
|
92
|
+
content-disposition: form-data; name="#{name}"\r
|
91
93
|
\r
|
92
94
|
#{file}\r
|
93
95
|
EOF
|