rack 1.5.5 → 1.6.0.beta
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/KNOWN-ISSUES +14 -0
- data/README.rdoc +10 -6
- data/Rakefile +3 -4
- data/SPEC +59 -23
- data/lib/rack.rb +2 -1
- data/lib/rack/auth/abstract/request.rb +1 -1
- data/lib/rack/auth/basic.rb +1 -1
- data/lib/rack/auth/digest/md5.rb +1 -1
- data/lib/rack/backports/uri/common_18.rb +1 -1
- data/lib/rack/builder.rb +19 -4
- data/lib/rack/cascade.rb +2 -2
- data/lib/rack/chunked.rb +12 -1
- data/lib/rack/commonlogger.rb +13 -5
- data/lib/rack/conditionalget.rb +14 -2
- data/lib/rack/content_length.rb +5 -1
- data/lib/rack/deflater.rb +52 -13
- data/lib/rack/directory.rb +8 -2
- data/lib/rack/etag.rb +14 -6
- data/lib/rack/file.rb +10 -14
- data/lib/rack/handler.rb +2 -0
- data/lib/rack/handler/fastcgi.rb +4 -1
- data/lib/rack/handler/mongrel.rb +8 -2
- data/lib/rack/handler/scgi.rb +4 -1
- data/lib/rack/handler/thin.rb +8 -2
- data/lib/rack/handler/webrick.rb +46 -6
- data/lib/rack/head.rb +7 -2
- data/lib/rack/lint.rb +73 -25
- data/lib/rack/lobster.rb +8 -3
- data/lib/rack/methodoverride.rb +14 -3
- data/lib/rack/mime.rb +1 -15
- data/lib/rack/mock.rb +15 -7
- data/lib/rack/multipart.rb +2 -2
- data/lib/rack/multipart/parser.rb +107 -53
- data/lib/rack/multipart/uploaded_file.rb +2 -2
- data/lib/rack/nulllogger.rb +21 -2
- data/lib/rack/request.rb +38 -24
- data/lib/rack/response.rb +5 -0
- data/lib/rack/sendfile.rb +10 -5
- data/lib/rack/server.rb +45 -17
- data/lib/rack/session/abstract/id.rb +7 -6
- data/lib/rack/session/cookie.rb +17 -7
- data/lib/rack/session/memcache.rb +4 -4
- data/lib/rack/session/pool.rb +3 -6
- data/lib/rack/showexceptions.rb +20 -11
- data/lib/rack/showstatus.rb +1 -1
- data/lib/rack/static.rb +27 -30
- data/lib/rack/tempfile_reaper.rb +22 -0
- data/lib/rack/urlmap.rb +17 -3
- data/lib/rack/utils.rb +78 -47
- data/lib/rack/utils/okjson.rb +90 -91
- data/rack.gemspec +3 -3
- data/test/multipart/filename_and_no_name +6 -0
- data/test/multipart/invalid_character +6 -0
- data/test/spec_builder.rb +13 -4
- data/test/spec_chunked.rb +16 -0
- data/test/spec_commonlogger.rb +36 -0
- data/test/spec_content_length.rb +3 -1
- data/test/spec_deflater.rb +283 -148
- data/test/spec_etag.rb +11 -2
- data/test/spec_file.rb +11 -3
- data/test/spec_head.rb +2 -0
- data/test/spec_lobster.rb +1 -1
- data/test/spec_mock.rb +8 -0
- data/test/spec_multipart.rb +111 -49
- data/test/spec_request.rb +109 -25
- data/test/spec_response.rb +30 -0
- data/test/spec_server.rb +20 -5
- data/test/spec_session_cookie.rb +45 -2
- data/test/spec_session_memcache.rb +1 -1
- data/test/spec_showexceptions.rb +29 -36
- data/test/spec_showstatus.rb +19 -0
- data/test/spec_tempfile_reaper.rb +63 -0
- data/test/spec_urlmap.rb +23 -0
- data/test/spec_utils.rb +60 -10
- data/test/spec_webrick.rb +41 -0
- metadata +12 -9
- data/test/cgi/lighttpd.errors +0 -1
- data/test/multipart/three_files_three_fields +0 -31
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b7e9fdbcce0cd16bdeda0ee39e9aa066e2dbcb17
|
4
|
+
data.tar.gz: 1be24bd36bc380d25cb5ef7bff5bf2abab269412
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1f4730c383cd5346a255fe4a179470653370f345ccf508389bf4149c744908b195ec3676eb564f5bf434e261d698230c7ba38dd7d192ddd022c1df9d9c0f7bf7
|
7
|
+
data.tar.gz: 42f1f9f7239286710e4b3b58f142cd673fe66e56b9e42ec45c2c7a3406079118f2dd1684c165404d9f77e482129335fa315ef179fefd0711c0f59156c4ca7a31
|
data/KNOWN-ISSUES
CHANGED
@@ -28,3 +28,17 @@
|
|
28
28
|
|
29
29
|
Since lighttpd 1.4.23, you also can use the "fix-root-scriptname" flag
|
30
30
|
in fastcgi.server.
|
31
|
+
|
32
|
+
= Known conflicts regarding parameter parsing
|
33
|
+
|
34
|
+
* Many users have differing opinions about parameter parsing. The current
|
35
|
+
parameter parsers in Rack are based on a combination of the HTTP and CGI
|
36
|
+
specs, and are intended to round-trip encoding and decoding. There are some
|
37
|
+
choices that may be viewed as deficiencies, specifically:
|
38
|
+
- Rack does not create implicit arrays for multiple instances of a parameter
|
39
|
+
- Rack returns nil when a value is not given
|
40
|
+
- Rack does not support multi-type keys in parameters
|
41
|
+
These issues or choices, will not be fixed before 2.0, if at all. They are
|
42
|
+
very major breaking changes. Users are free to write alternative parameter
|
43
|
+
parsers, and their own Request and Response wrappers. Moreover, users are
|
44
|
+
encouraged to do so.
|
data/README.rdoc
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
= Rack, a modular Ruby webserver interface {<img src="https://secure.travis-ci.org/rack/rack.
|
1
|
+
= Rack, a modular Ruby webserver interface {<img src="https://secure.travis-ci.org/rack/rack.svg" alt="Build Status" />}[http://travis-ci.org/rack/rack] {<img src="https://gemnasium.com/rack/rack.svg" alt="Dependency Status" />}[https://gemnasium.com/rack/rack]
|
2
2
|
|
3
3
|
Rack provides a minimal, modular and adaptable interface for developing
|
4
4
|
web applications in Ruby. By wrapping HTTP requests and responses in
|
@@ -33,6 +33,7 @@ These web servers include Rack handlers in their distributions:
|
|
33
33
|
* Unicorn
|
34
34
|
* unixrack
|
35
35
|
* uWSGI
|
36
|
+
* yahns
|
36
37
|
* Zbatery
|
37
38
|
|
38
39
|
Any valid Rack app will run the same on all these handlers, without
|
@@ -528,8 +529,6 @@ run on port 11211) and memcache-client installed.
|
|
528
529
|
* Fix a race condition that could result in overwritten pidfiles
|
529
530
|
* Various documentation additions
|
530
531
|
|
531
|
-
* Prevent extremely deep parameters from being parsed. CVE-2015-3225
|
532
|
-
|
533
532
|
== Contact
|
534
533
|
|
535
534
|
Please post bugs, suggestions and patches to
|
@@ -557,12 +556,17 @@ The Rack Core Team, consisting of
|
|
557
556
|
* Christian Neukirchen (chneukirchen)
|
558
557
|
* James Tucker (raggi)
|
559
558
|
* Josh Peek (josh)
|
559
|
+
* José Valim (josevalim)
|
560
560
|
* Michael Fellinger (manveru)
|
561
|
-
* Ryan Tomayko (rtomayko)
|
562
|
-
* Scytrin dai Kinthra (scytrin)
|
563
561
|
* Aaron Patterson (tenderlove)
|
562
|
+
* Santiago Pastorino (spastorino)
|
564
563
|
* Konstantin Haase (rkh)
|
565
564
|
|
565
|
+
and the Rack Alumnis
|
566
|
+
|
567
|
+
* Ryan Tomayko (rtomayko)
|
568
|
+
* Scytrin dai Kinthra (scytrin)
|
569
|
+
|
566
570
|
would like to thank:
|
567
571
|
|
568
572
|
* Adrian Madrid, for the LiteSpeed handler.
|
@@ -616,7 +620,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
616
620
|
|
617
621
|
== Links
|
618
622
|
|
619
|
-
Rack:: <http://rack.github.
|
623
|
+
Rack:: <http://rack.github.io/>
|
620
624
|
Official Rack repositories:: <http://github.com/rack>
|
621
625
|
Rack Bug Tracking:: <http://github.com/rack/rack/issues>
|
622
626
|
rack-devel mailing list:: <http://groups.google.com/group/rack-devel>
|
data/Rakefile
CHANGED
@@ -6,7 +6,6 @@ task :default => [:test]
|
|
6
6
|
desc "Install gem dependencies"
|
7
7
|
task :deps do
|
8
8
|
require 'rubygems'
|
9
|
-
require 'rbconfig'
|
10
9
|
spec = Gem::Specification.load('rack.gemspec')
|
11
10
|
spec.dependencies.each do |dep|
|
12
11
|
reqs = dep.requirements_list
|
@@ -33,7 +32,7 @@ task :officialrelease do
|
|
33
32
|
end
|
34
33
|
|
35
34
|
task :officialrelease_really => %w[SPEC dist gem] do
|
36
|
-
sh "
|
35
|
+
sh "sha1sum #{release}.tar.gz #{release}.gem"
|
37
36
|
end
|
38
37
|
|
39
38
|
def release
|
@@ -42,8 +41,8 @@ end
|
|
42
41
|
|
43
42
|
desc "Make binaries executable"
|
44
43
|
task :chmod do
|
45
|
-
Dir["bin/*"].each { |binary| File.chmod(
|
46
|
-
Dir["test/cgi/test*"].each { |binary| File.chmod(
|
44
|
+
Dir["bin/*"].each { |binary| File.chmod(0755, binary) }
|
45
|
+
Dir["test/cgi/test*"].each { |binary| File.chmod(0755, binary) }
|
47
46
|
end
|
48
47
|
|
49
48
|
desc "Generate a ChangeLog"
|
data/SPEC
CHANGED
@@ -40,7 +40,17 @@ below.
|
|
40
40
|
<tt>QUERY_STRING</tt>:: The portion of the request URL that
|
41
41
|
follows the <tt>?</tt>, if any. May be
|
42
42
|
empty, but is always required!
|
43
|
-
<tt>SERVER_NAME</tt>, <tt>SERVER_PORT</tt>::
|
43
|
+
<tt>SERVER_NAME</tt>, <tt>SERVER_PORT</tt>::
|
44
|
+
When combined with <tt>SCRIPT_NAME</tt> and
|
45
|
+
<tt>PATH_INFO</tt>, these variables can be
|
46
|
+
used to complete the URL. Note, however,
|
47
|
+
that <tt>HTTP_HOST</tt>, if present,
|
48
|
+
should be used in preference to
|
49
|
+
<tt>SERVER_NAME</tt> for reconstructing
|
50
|
+
the request URL.
|
51
|
+
<tt>SERVER_NAME</tt> and <tt>SERVER_PORT</tt>
|
52
|
+
can never be empty strings, and so
|
53
|
+
are always required.
|
44
54
|
<tt>HTTP_</tt> Variables:: Variables corresponding to the
|
45
55
|
client-supplied HTTP request
|
46
56
|
headers (i.e., variables whose
|
@@ -49,24 +59,47 @@ below.
|
|
49
59
|
variables should correspond with
|
50
60
|
the presence or absence of the
|
51
61
|
appropriate HTTP header in the
|
52
|
-
request. See
|
53
|
-
|
62
|
+
request. See
|
63
|
+
<a href="https://tools.ietf.org/html/rfc3875#section-4.1.18">
|
64
|
+
RFC3875 section 4.1.18</a> for
|
65
|
+
specific behavior.
|
54
66
|
In addition to this, the Rack environment must include these
|
55
67
|
Rack-specific variables:
|
56
|
-
<tt>rack.version</tt>:: The Array representing this version of Rack
|
57
|
-
|
68
|
+
<tt>rack.version</tt>:: The Array representing this version of Rack
|
69
|
+
See Rack::VERSION, that corresponds to
|
70
|
+
the version of this SPEC.
|
71
|
+
<tt>rack.url_scheme</tt>:: +http+ or +https+, depending on the
|
72
|
+
request URL.
|
58
73
|
<tt>rack.input</tt>:: See below, the input stream.
|
59
74
|
<tt>rack.errors</tt>:: See below, the error stream.
|
60
|
-
<tt>rack.multithread</tt>:: true if the application object may be
|
61
|
-
|
62
|
-
|
63
|
-
<tt>rack.
|
64
|
-
|
65
|
-
|
75
|
+
<tt>rack.multithread</tt>:: true if the application object may be
|
76
|
+
simultaneously invoked by another thread
|
77
|
+
in the same process, false otherwise.
|
78
|
+
<tt>rack.multiprocess</tt>:: true if an equivalent application object
|
79
|
+
may be simultaneously invoked by another
|
80
|
+
process, false otherwise.
|
81
|
+
<tt>rack.run_once</tt>:: true if the server expects
|
82
|
+
(but does not guarantee!) that the
|
83
|
+
application will only be invoked this one
|
84
|
+
time during the life of its containing
|
85
|
+
process. Normally, this will only be true
|
86
|
+
for a server based on CGI
|
87
|
+
(or something similar).
|
88
|
+
<tt>rack.hijack?</tt>:: present and true if the server supports
|
89
|
+
connection hijacking. See below, hijacking.
|
90
|
+
<tt>rack.hijack</tt>:: an object responding to #call that must be
|
91
|
+
called at least once before using
|
92
|
+
rack.hijack_io.
|
93
|
+
It is recommended #call return rack.hijack_io
|
94
|
+
as well as setting it in env if necessary.
|
95
|
+
<tt>rack.hijack_io</tt>:: if rack.hijack? is true, and rack.hijack
|
96
|
+
has received #call, this will contain
|
97
|
+
an object resembling an IO. See hijacking.
|
66
98
|
Additional environment specifications have approved to
|
67
99
|
standardized middleware APIs. None of these are required to
|
68
100
|
be implemented by the server.
|
69
|
-
<tt>rack.session</tt>:: A hash like interface for storing
|
101
|
+
<tt>rack.session</tt>:: A hash like interface for storing
|
102
|
+
request session data.
|
70
103
|
The store must implement:
|
71
104
|
store(key, value) (aliased as []=);
|
72
105
|
fetch(key, default = nil) (aliased as []);
|
@@ -110,15 +143,18 @@ must be opened in binary mode, for Ruby 1.9 compatibility.
|
|
110
143
|
The input stream must respond to +gets+, +each+, +read+ and +rewind+.
|
111
144
|
* +gets+ must be called without arguments and return a string,
|
112
145
|
or +nil+ on EOF.
|
113
|
-
* +read+ behaves like IO#read.
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
then this method reads
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
146
|
+
* +read+ behaves like IO#read.
|
147
|
+
Its signature is <tt>read([length, [buffer]])</tt>.
|
148
|
+
If given, +length+ must be a non-negative Integer (>= 0) or +nil+,
|
149
|
+
and +buffer+ must be a String and may not be nil.
|
150
|
+
If +length+ is given and not nil, then this method reads at most
|
151
|
+
+length+ bytes from the input stream.
|
152
|
+
If +length+ is not given or nil, then this method reads
|
153
|
+
all data until EOF.
|
154
|
+
When EOF is reached, this method returns nil if +length+ is given
|
155
|
+
and not nil, or "" if +length+ is not given or is nil.
|
156
|
+
If +buffer+ is given, then the read data will be placed
|
157
|
+
into +buffer+ instead of a newly created String object.
|
122
158
|
* +each+ must be called without arguments and only yield Strings.
|
123
159
|
* +rewind+ must be called without arguments. It rewinds the input
|
124
160
|
stream back to the beginning. It must not raise Errno::ESPIPE:
|
@@ -207,7 +243,7 @@ but only contain keys that consist of
|
|
207
243
|
letters, digits, <tt>_</tt> or <tt>-</tt> and start with a letter.
|
208
244
|
The values of the header must be Strings,
|
209
245
|
consisting of lines (for multiple header values, e.g. multiple
|
210
|
-
<tt>Set-Cookie</tt> values)
|
246
|
+
<tt>Set-Cookie</tt> values) separated by "\\n".
|
211
247
|
The lines must not contain characters below 037.
|
212
248
|
=== The Content-Type
|
213
249
|
There must not be a <tt>Content-Type</tt>, when the +Status+ is 1xx,
|
@@ -222,7 +258,7 @@ The Body itself should not be an instance of String, as this will
|
|
222
258
|
break in Ruby 1.9.
|
223
259
|
If the Body responds to +close+, it will be called after iteration. If
|
224
260
|
the body is replaced by a middleware after action, the original body
|
225
|
-
must be closed first, if it
|
261
|
+
must be closed first, if it responds to close.
|
226
262
|
If the Body responds to +to_path+, it must return a String
|
227
263
|
identifying the location of a file whose contents are identical
|
228
264
|
to that produced by calling +each+; this may be used by the
|
data/lib/rack.rb
CHANGED
@@ -20,7 +20,7 @@ module Rack
|
|
20
20
|
|
21
21
|
# Return the Rack release as a dotted string.
|
22
22
|
def self.release
|
23
|
-
"1.5
|
23
|
+
"1.5"
|
24
24
|
end
|
25
25
|
|
26
26
|
autoload :Builder, "rack/builder"
|
@@ -53,6 +53,7 @@ module Rack
|
|
53
53
|
autoload :ShowExceptions, "rack/showexceptions"
|
54
54
|
autoload :ShowStatus, "rack/showstatus"
|
55
55
|
autoload :Static, "rack/static"
|
56
|
+
autoload :TempfileReaper, "rack/tempfile_reaper"
|
56
57
|
autoload :URLMap, "rack/urlmap"
|
57
58
|
autoload :Utils, "rack/utils"
|
58
59
|
autoload :Multipart, "rack/multipart"
|
data/lib/rack/auth/basic.rb
CHANGED
data/lib/rack/auth/digest/md5.rb
CHANGED
data/lib/rack/builder.rb
CHANGED
@@ -51,7 +51,7 @@ module Rack
|
|
51
51
|
end
|
52
52
|
|
53
53
|
def initialize(default_app = nil,&block)
|
54
|
-
@use, @map, @run = [], nil, default_app
|
54
|
+
@use, @map, @run, @warmup = [], nil, default_app, nil
|
55
55
|
instance_eval(&block) if block_given?
|
56
56
|
end
|
57
57
|
|
@@ -73,7 +73,7 @@ module Rack
|
|
73
73
|
# end
|
74
74
|
#
|
75
75
|
# use Middleware
|
76
|
-
# run lambda { |env| [200, { "Content-Type => "text/plain" }, ["OK"]] }
|
76
|
+
# run lambda { |env| [200, { "Content-Type" => "text/plain" }, ["OK"]] }
|
77
77
|
#
|
78
78
|
# All requests through to this application will first be processed by the middleware class.
|
79
79
|
# The +call+ method in this example sets an additional environment key which then can be
|
@@ -104,6 +104,19 @@ module Rack
|
|
104
104
|
@run = app
|
105
105
|
end
|
106
106
|
|
107
|
+
# Takes a lambda or block that is used to warm-up the application.
|
108
|
+
#
|
109
|
+
# warmup do |app|
|
110
|
+
# client = Rack::MockRequest.new(app)
|
111
|
+
# client.get('/')
|
112
|
+
# end
|
113
|
+
#
|
114
|
+
# use SomeMiddleware
|
115
|
+
# run MyApp
|
116
|
+
def warmup(prc=nil, &block)
|
117
|
+
@warmup = prc || block
|
118
|
+
end
|
119
|
+
|
107
120
|
# Creates a route within the application.
|
108
121
|
#
|
109
122
|
# Rack::Builder.app do
|
@@ -131,7 +144,9 @@ module Rack
|
|
131
144
|
def to_app
|
132
145
|
app = @map ? generate_map(@run, @map) : @run
|
133
146
|
fail "missing run or map statement" unless app
|
134
|
-
@use.reverse.inject(app) { |a,e| e[a] }
|
147
|
+
app = @use.reverse.inject(app) { |a,e| e[a] }
|
148
|
+
@warmup.call(app) if @warmup
|
149
|
+
app
|
135
150
|
end
|
136
151
|
|
137
152
|
def call(env)
|
@@ -142,7 +157,7 @@ module Rack
|
|
142
157
|
|
143
158
|
def generate_map(default_app, mapping)
|
144
159
|
mapped = default_app ? {'/' => default_app} : {}
|
145
|
-
mapping.each { |r,b| mapped[r] = self.class.new(default_app, &b) }
|
160
|
+
mapping.each { |r,b| mapped[r] = self.class.new(default_app, &b).to_app }
|
146
161
|
URLMap.new(mapped)
|
147
162
|
end
|
148
163
|
end
|
data/lib/rack/cascade.rb
CHANGED
data/lib/rack/chunked.rb
CHANGED
@@ -39,11 +39,22 @@ module Rack
|
|
39
39
|
@app = app
|
40
40
|
end
|
41
41
|
|
42
|
+
# pre-HTTP/1.0 (informally "HTTP/0.9") HTTP requests did not have
|
43
|
+
# a version (nor response headers)
|
44
|
+
def chunkable_version?(ver)
|
45
|
+
case ver
|
46
|
+
when "HTTP/1.0", nil, "HTTP/0.9"
|
47
|
+
false
|
48
|
+
else
|
49
|
+
true
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
42
53
|
def call(env)
|
43
54
|
status, headers, body = @app.call(env)
|
44
55
|
headers = HeaderHash.new(headers)
|
45
56
|
|
46
|
-
if env['HTTP_VERSION']
|
57
|
+
if ! chunkable_version?(env['HTTP_VERSION']) ||
|
47
58
|
STATUS_WITH_NO_ENTITY_BODY.include?(status) ||
|
48
59
|
headers['Content-Length'] ||
|
49
60
|
headers['Transfer-Encoding']
|
data/lib/rack/commonlogger.rb
CHANGED
@@ -10,7 +10,7 @@ module Rack
|
|
10
10
|
# an instance of Rack::NullLogger.
|
11
11
|
#
|
12
12
|
# +logger+ can be any class, including the standard library Logger, and is
|
13
|
-
# expected to have
|
13
|
+
# expected to have either +write+ or +<<+ method, which accepts the CommonLogger::FORMAT.
|
14
14
|
# According to the SPEC, the error stream must also respond to +puts+
|
15
15
|
# (which takes a single argument that responds to +to_s+), and +flush+
|
16
16
|
# (which is called without arguments in order to make the error appear for
|
@@ -18,7 +18,7 @@ module Rack
|
|
18
18
|
class CommonLogger
|
19
19
|
# Common Log Format: http://httpd.apache.org/docs/1.3/logs.html#common
|
20
20
|
#
|
21
|
-
# lilith.local - - [07/Aug/2006 23:58:02] "GET / HTTP/1.1" 500 -
|
21
|
+
# lilith.local - - [07/Aug/2006 23:58:02 -0400] "GET / HTTP/1.1" 500 -
|
22
22
|
#
|
23
23
|
# %{%s - %s [%s] "%s %s%s %s" %d %s\n} %
|
24
24
|
FORMAT = %{%s - %s [%s] "%s %s%s %s" %d %s %0.4f\n}
|
@@ -42,11 +42,10 @@ module Rack
|
|
42
42
|
now = Time.now
|
43
43
|
length = extract_content_length(header)
|
44
44
|
|
45
|
-
|
46
|
-
logger.write FORMAT % [
|
45
|
+
msg = FORMAT % [
|
47
46
|
env['HTTP_X_FORWARDED_FOR'] || env["REMOTE_ADDR"] || "-",
|
48
47
|
env["REMOTE_USER"] || "-",
|
49
|
-
now.strftime("%d/%b/%Y
|
48
|
+
now.strftime("%d/%b/%Y:%H:%M:%S %z"),
|
50
49
|
env["REQUEST_METHOD"],
|
51
50
|
env["PATH_INFO"],
|
52
51
|
env["QUERY_STRING"].empty? ? "" : "?"+env["QUERY_STRING"],
|
@@ -54,6 +53,15 @@ module Rack
|
|
54
53
|
status.to_s[0..3],
|
55
54
|
length,
|
56
55
|
now - began_at ]
|
56
|
+
|
57
|
+
logger = @logger || env['rack.errors']
|
58
|
+
# Standard library logger doesn't support write but it supports << which actually
|
59
|
+
# calls to write on the log device without formatting
|
60
|
+
if logger.respond_to?(:write)
|
61
|
+
logger.write(msg)
|
62
|
+
else
|
63
|
+
logger << msg
|
64
|
+
end
|
57
65
|
end
|
58
66
|
|
59
67
|
def extract_content_length(headers)
|
data/lib/rack/conditionalget.rb
CHANGED
@@ -28,7 +28,10 @@ module Rack
|
|
28
28
|
status = 304
|
29
29
|
headers.delete('Content-Type')
|
30
30
|
headers.delete('Content-Length')
|
31
|
-
|
31
|
+
original_body = body
|
32
|
+
body = Rack::BodyProxy.new([]) do
|
33
|
+
original_body.close if original_body.respond_to?(:close)
|
34
|
+
end
|
32
35
|
end
|
33
36
|
[status, headers, body]
|
34
37
|
else
|
@@ -61,7 +64,16 @@ module Rack
|
|
61
64
|
end
|
62
65
|
|
63
66
|
def to_rfc2822(since)
|
64
|
-
|
67
|
+
# shortest possible valid date is the obsolete: 1 Nov 97 09:55 A
|
68
|
+
# anything shorter is invalid, this avoids exceptions for common cases
|
69
|
+
# most common being the empty string
|
70
|
+
if since && since.length >= 16
|
71
|
+
# NOTE: there is no trivial way to write this in a non execption way
|
72
|
+
# _rfc2822 returns a hash but is not that usable
|
73
|
+
Time.rfc2822(since) rescue nil
|
74
|
+
else
|
75
|
+
nil
|
76
|
+
end
|
65
77
|
end
|
66
78
|
end
|
67
79
|
end
|