rack 2.0.8 → 2.2.2

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 (190) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +690 -0
  3. data/CONTRIBUTING.md +136 -0
  4. data/{COPYING → MIT-LICENSE} +4 -2
  5. data/README.rdoc +152 -148
  6. data/Rakefile +37 -23
  7. data/{SPEC → SPEC.rdoc} +29 -5
  8. data/bin/rackup +1 -0
  9. data/example/lobster.ru +2 -0
  10. data/example/protectedlobster.rb +3 -1
  11. data/example/protectedlobster.ru +2 -0
  12. data/lib/rack.rb +67 -73
  13. data/lib/rack/auth/abstract/handler.rb +3 -1
  14. data/lib/rack/auth/abstract/request.rb +1 -1
  15. data/lib/rack/auth/basic.rb +7 -4
  16. data/lib/rack/auth/digest/md5.rb +13 -11
  17. data/lib/rack/auth/digest/nonce.rb +6 -3
  18. data/lib/rack/auth/digest/params.rb +4 -2
  19. data/lib/rack/auth/digest/request.rb +5 -3
  20. data/lib/rack/body_proxy.rb +15 -14
  21. data/lib/rack/builder.rb +116 -23
  22. data/lib/rack/cascade.rb +28 -12
  23. data/lib/rack/chunked.rb +68 -20
  24. data/lib/rack/common_logger.rb +33 -25
  25. data/lib/rack/conditional_get.rb +20 -16
  26. data/lib/rack/config.rb +2 -0
  27. data/lib/rack/content_length.rb +8 -7
  28. data/lib/rack/content_type.rb +5 -4
  29. data/lib/rack/core_ext/regexp.rb +14 -0
  30. data/lib/rack/deflater.rb +59 -34
  31. data/lib/rack/directory.rb +84 -64
  32. data/lib/rack/etag.rb +5 -4
  33. data/lib/rack/events.rb +19 -20
  34. data/lib/rack/file.rb +4 -173
  35. data/lib/rack/files.rb +218 -0
  36. data/lib/rack/handler.rb +7 -2
  37. data/lib/rack/handler/cgi.rb +2 -3
  38. data/lib/rack/handler/fastcgi.rb +4 -4
  39. data/lib/rack/handler/lsws.rb +3 -3
  40. data/lib/rack/handler/scgi.rb +9 -8
  41. data/lib/rack/handler/thin.rb +3 -3
  42. data/lib/rack/handler/webrick.rb +15 -6
  43. data/lib/rack/head.rb +1 -1
  44. data/lib/rack/lint.rb +71 -25
  45. data/lib/rack/lobster.rb +10 -10
  46. data/lib/rack/lock.rb +2 -1
  47. data/lib/rack/logger.rb +2 -0
  48. data/lib/rack/media_type.rb +10 -5
  49. data/lib/rack/method_override.rb +4 -2
  50. data/lib/rack/mime.rb +9 -1
  51. data/lib/rack/mock.rb +97 -20
  52. data/lib/rack/multipart.rb +6 -4
  53. data/lib/rack/multipart/generator.rb +17 -13
  54. data/lib/rack/multipart/parser.rb +54 -56
  55. data/lib/rack/multipart/uploaded_file.rb +15 -7
  56. data/lib/rack/null_logger.rb +2 -0
  57. data/lib/rack/query_parser.rb +53 -28
  58. data/lib/rack/recursive.rb +7 -5
  59. data/lib/rack/reloader.rb +8 -4
  60. data/lib/rack/request.rb +220 -61
  61. data/lib/rack/response.rb +127 -44
  62. data/lib/rack/rewindable_input.rb +4 -3
  63. data/lib/rack/runtime.rb +6 -4
  64. data/lib/rack/sendfile.rb +13 -9
  65. data/lib/rack/server.rb +95 -24
  66. data/lib/rack/session/abstract/id.rb +36 -23
  67. data/lib/rack/session/cookie.rb +11 -12
  68. data/lib/rack/session/memcache.rb +4 -93
  69. data/lib/rack/session/pool.rb +5 -3
  70. data/lib/rack/show_exceptions.rb +21 -17
  71. data/lib/rack/show_status.rb +9 -9
  72. data/lib/rack/static.rb +23 -11
  73. data/lib/rack/tempfile_reaper.rb +1 -1
  74. data/lib/rack/urlmap.rb +12 -6
  75. data/lib/rack/utils.rb +98 -109
  76. data/lib/rack/version.rb +29 -0
  77. data/rack.gemspec +40 -28
  78. metadata +36 -177
  79. data/HISTORY.md +0 -505
  80. data/test/builder/an_underscore_app.rb +0 -5
  81. data/test/builder/anything.rb +0 -5
  82. data/test/builder/comment.ru +0 -4
  83. data/test/builder/end.ru +0 -5
  84. data/test/builder/line.ru +0 -1
  85. data/test/builder/options.ru +0 -2
  86. data/test/cgi/assets/folder/test.js +0 -1
  87. data/test/cgi/assets/fonts/font.eot +0 -1
  88. data/test/cgi/assets/images/image.png +0 -1
  89. data/test/cgi/assets/index.html +0 -1
  90. data/test/cgi/assets/javascripts/app.js +0 -1
  91. data/test/cgi/assets/stylesheets/app.css +0 -1
  92. data/test/cgi/lighttpd.conf +0 -26
  93. data/test/cgi/rackup_stub.rb +0 -6
  94. data/test/cgi/sample_rackup.ru +0 -5
  95. data/test/cgi/test +0 -9
  96. data/test/cgi/test+directory/test+file +0 -1
  97. data/test/cgi/test.fcgi +0 -9
  98. data/test/cgi/test.gz +0 -0
  99. data/test/cgi/test.ru +0 -5
  100. data/test/gemloader.rb +0 -10
  101. data/test/helper.rb +0 -34
  102. data/test/multipart/bad_robots +0 -259
  103. data/test/multipart/binary +0 -0
  104. data/test/multipart/content_type_and_no_filename +0 -6
  105. data/test/multipart/empty +0 -10
  106. data/test/multipart/fail_16384_nofile +0 -814
  107. data/test/multipart/file1.txt +0 -1
  108. data/test/multipart/filename_and_modification_param +0 -7
  109. data/test/multipart/filename_and_no_name +0 -6
  110. data/test/multipart/filename_with_encoded_words +0 -7
  111. data/test/multipart/filename_with_escaped_quotes +0 -6
  112. data/test/multipart/filename_with_escaped_quotes_and_modification_param +0 -7
  113. data/test/multipart/filename_with_null_byte +0 -7
  114. data/test/multipart/filename_with_percent_escaped_quotes +0 -6
  115. data/test/multipart/filename_with_single_quote +0 -7
  116. data/test/multipart/filename_with_unescaped_percentages +0 -6
  117. data/test/multipart/filename_with_unescaped_percentages2 +0 -6
  118. data/test/multipart/filename_with_unescaped_percentages3 +0 -6
  119. data/test/multipart/filename_with_unescaped_quotes +0 -6
  120. data/test/multipart/ie +0 -6
  121. data/test/multipart/invalid_character +0 -6
  122. data/test/multipart/mixed_files +0 -21
  123. data/test/multipart/nested +0 -10
  124. data/test/multipart/none +0 -9
  125. data/test/multipart/quoted +0 -15
  126. data/test/multipart/rack-logo.png +0 -0
  127. data/test/multipart/semicolon +0 -6
  128. data/test/multipart/text +0 -15
  129. data/test/multipart/three_files_three_fields +0 -31
  130. data/test/multipart/unity3d_wwwform +0 -11
  131. data/test/multipart/webkit +0 -32
  132. data/test/rackup/config.ru +0 -31
  133. data/test/registering_handler/rack/handler/registering_myself.rb +0 -8
  134. data/test/spec_auth_basic.rb +0 -89
  135. data/test/spec_auth_digest.rb +0 -260
  136. data/test/spec_body_proxy.rb +0 -85
  137. data/test/spec_builder.rb +0 -233
  138. data/test/spec_cascade.rb +0 -63
  139. data/test/spec_cgi.rb +0 -84
  140. data/test/spec_chunked.rb +0 -103
  141. data/test/spec_common_logger.rb +0 -95
  142. data/test/spec_conditional_get.rb +0 -103
  143. data/test/spec_config.rb +0 -23
  144. data/test/spec_content_length.rb +0 -86
  145. data/test/spec_content_type.rb +0 -46
  146. data/test/spec_deflater.rb +0 -375
  147. data/test/spec_directory.rb +0 -148
  148. data/test/spec_etag.rb +0 -108
  149. data/test/spec_events.rb +0 -133
  150. data/test/spec_fastcgi.rb +0 -85
  151. data/test/spec_file.rb +0 -264
  152. data/test/spec_handler.rb +0 -57
  153. data/test/spec_head.rb +0 -46
  154. data/test/spec_lint.rb +0 -515
  155. data/test/spec_lobster.rb +0 -59
  156. data/test/spec_lock.rb +0 -204
  157. data/test/spec_logger.rb +0 -24
  158. data/test/spec_media_type.rb +0 -42
  159. data/test/spec_method_override.rb +0 -110
  160. data/test/spec_mime.rb +0 -51
  161. data/test/spec_mock.rb +0 -359
  162. data/test/spec_multipart.rb +0 -722
  163. data/test/spec_null_logger.rb +0 -21
  164. data/test/spec_recursive.rb +0 -75
  165. data/test/spec_request.rb +0 -1407
  166. data/test/spec_response.rb +0 -510
  167. data/test/spec_rewindable_input.rb +0 -128
  168. data/test/spec_runtime.rb +0 -50
  169. data/test/spec_sendfile.rb +0 -125
  170. data/test/spec_server.rb +0 -193
  171. data/test/spec_session_abstract_id.rb +0 -31
  172. data/test/spec_session_abstract_session_hash.rb +0 -45
  173. data/test/spec_session_cookie.rb +0 -442
  174. data/test/spec_session_memcache.rb +0 -357
  175. data/test/spec_session_pool.rb +0 -247
  176. data/test/spec_show_exceptions.rb +0 -93
  177. data/test/spec_show_status.rb +0 -104
  178. data/test/spec_static.rb +0 -184
  179. data/test/spec_tempfile_reaper.rb +0 -64
  180. data/test/spec_thin.rb +0 -96
  181. data/test/spec_urlmap.rb +0 -237
  182. data/test/spec_utils.rb +0 -742
  183. data/test/spec_version.rb +0 -11
  184. data/test/spec_webrick.rb +0 -206
  185. data/test/static/another/index.html +0 -1
  186. data/test/static/foo.html +0 -1
  187. data/test/static/index.html +0 -1
  188. data/test/testrequest.rb +0 -78
  189. data/test/unregistered_handler/rack/handler/unregistered.rb +0 -7
  190. data/test/unregistered_handler/rack/handler/unregistered_long_one.rb +0 -7
@@ -1,128 +0,0 @@
1
- require 'minitest/autorun'
2
- require 'stringio'
3
- require 'rack/rewindable_input'
4
-
5
- module RewindableTest
6
- extend Minitest::Spec::DSL
7
-
8
- def setup
9
- @rio = Rack::RewindableInput.new(@io)
10
- end
11
-
12
- class << self # HACK to get this running w/ as few changes as possible
13
- alias_method :should, :it
14
- end
15
-
16
- it "be able to handle to read()" do
17
- @rio.read.must_equal "hello world"
18
- end
19
-
20
- it "be able to handle to read(nil)" do
21
- @rio.read(nil).must_equal "hello world"
22
- end
23
-
24
- it "be able to handle to read(length)" do
25
- @rio.read(1).must_equal "h"
26
- end
27
-
28
- it "be able to handle to read(length, buffer)" do
29
- buffer = ""
30
- result = @rio.read(1, buffer)
31
- result.must_equal "h"
32
- result.object_id.must_equal buffer.object_id
33
- end
34
-
35
- it "be able to handle to read(nil, buffer)" do
36
- buffer = ""
37
- result = @rio.read(nil, buffer)
38
- result.must_equal "hello world"
39
- result.object_id.must_equal buffer.object_id
40
- end
41
-
42
- it "rewind to the beginning when #rewind is called" do
43
- @rio.read(1)
44
- @rio.rewind
45
- @rio.read.must_equal "hello world"
46
- end
47
-
48
- it "be able to handle gets" do
49
- @rio.gets.must_equal "hello world"
50
- end
51
-
52
- it "be able to handle each" do
53
- array = []
54
- @rio.each do |data|
55
- array << data
56
- end
57
- array.must_equal ["hello world"]
58
- end
59
-
60
- it "not buffer into a Tempfile if no data has been read yet" do
61
- @rio.instance_variable_get(:@rewindable_io).must_be_nil
62
- end
63
-
64
- it "buffer into a Tempfile when data has been consumed for the first time" do
65
- @rio.read(1)
66
- tempfile = @rio.instance_variable_get(:@rewindable_io)
67
- tempfile.wont_be :nil?
68
- @rio.read(1)
69
- tempfile2 = @rio.instance_variable_get(:@rewindable_io)
70
- tempfile2.path.must_equal tempfile.path
71
- end
72
-
73
- it "close the underlying tempfile upon calling #close" do
74
- @rio.read(1)
75
- tempfile = @rio.instance_variable_get(:@rewindable_io)
76
- @rio.close
77
- tempfile.must_be :closed?
78
- end
79
-
80
- it "be possible to call #close when no data has been buffered yet" do
81
- @rio.close.must_be_nil
82
- end
83
-
84
- it "be possible to call #close multiple times" do
85
- @rio.close.must_be_nil
86
- @rio.close.must_be_nil
87
- end
88
-
89
- after do
90
- @rio.close
91
- @rio = nil
92
- end
93
- end
94
-
95
- describe Rack::RewindableInput do
96
- describe "given an IO object that is already rewindable" do
97
- def setup
98
- @io = StringIO.new("hello world")
99
- super
100
- end
101
-
102
- include RewindableTest
103
- end
104
-
105
- describe "given an IO object that is not rewindable" do
106
- def setup
107
- @io = StringIO.new("hello world")
108
- @io.instance_eval do
109
- undef :rewind
110
- end
111
- super
112
- end
113
-
114
- include RewindableTest
115
- end
116
-
117
- describe "given an IO object whose rewind method raises Errno::ESPIPE" do
118
- def setup
119
- @io = StringIO.new("hello world")
120
- def @io.rewind
121
- raise Errno::ESPIPE, "You can't rewind this!"
122
- end
123
- super
124
- end
125
-
126
- include RewindableTest
127
- end
128
- end
@@ -1,50 +0,0 @@
1
- require 'minitest/autorun'
2
- require 'rack/lint'
3
- require 'rack/mock'
4
- require 'rack/runtime'
5
-
6
- describe Rack::Runtime do
7
- def runtime_app(app, *args)
8
- Rack::Lint.new Rack::Runtime.new(app, *args)
9
- end
10
-
11
- def request
12
- Rack::MockRequest.env_for
13
- end
14
-
15
- it "sets X-Runtime is none is set" do
16
- app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, "Hello, World!"] }
17
- response = runtime_app(app).call(request)
18
- response[1]['X-Runtime'].must_match(/[\d\.]+/)
19
- end
20
-
21
- it "doesn't set the X-Runtime if it is already set" do
22
- app = lambda { |env| [200, {'Content-Type' => 'text/plain', "X-Runtime" => "foobar"}, "Hello, World!"] }
23
- response = runtime_app(app).call(request)
24
- response[1]['X-Runtime'].must_equal "foobar"
25
- end
26
-
27
- it "allow a suffix to be set" do
28
- app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, "Hello, World!"] }
29
- response = runtime_app(app, "Test").call(request)
30
- response[1]['X-Runtime-Test'].must_match(/[\d\.]+/)
31
- end
32
-
33
- it "allow multiple timers to be set" do
34
- app = lambda { |env| sleep 0.1; [200, {'Content-Type' => 'text/plain'}, "Hello, World!"] }
35
- runtime = runtime_app(app, "App")
36
-
37
- # wrap many times to guarantee a measurable difference
38
- 100.times do |i|
39
- runtime = Rack::Runtime.new(runtime, i.to_s)
40
- end
41
- runtime = Rack::Runtime.new(runtime, "All")
42
-
43
- response = runtime.call(request)
44
-
45
- response[1]['X-Runtime-App'].must_match(/[\d\.]+/)
46
- response[1]['X-Runtime-All'].must_match(/[\d\.]+/)
47
-
48
- Float(response[1]['X-Runtime-All']).must_be :>, Float(response[1]['X-Runtime-App'])
49
- end
50
- end
@@ -1,125 +0,0 @@
1
- require 'minitest/autorun'
2
- require 'fileutils'
3
- require 'rack/lint'
4
- require 'rack/sendfile'
5
- require 'rack/mock'
6
- require 'tmpdir'
7
-
8
- describe Rack::Sendfile do
9
- def sendfile_body
10
- FileUtils.touch File.join(Dir.tmpdir, "rack_sendfile")
11
- res = ['Hello World']
12
- def res.to_path ; File.join(Dir.tmpdir, "rack_sendfile") ; end
13
- res
14
- end
15
-
16
- def simple_app(body=sendfile_body)
17
- lambda { |env| [200, {'Content-Type' => 'text/plain'}, body] }
18
- end
19
-
20
- def sendfile_app(body, mappings = [])
21
- Rack::Lint.new Rack::Sendfile.new(simple_app(body), nil, mappings)
22
- end
23
-
24
- def request(headers={}, body=sendfile_body, mappings=[])
25
- yield Rack::MockRequest.new(sendfile_app(body, mappings)).get('/', headers)
26
- end
27
-
28
- def open_file(path)
29
- Class.new(File) do
30
- unless method_defined?(:to_path)
31
- alias :to_path :path
32
- end
33
- end.open(path, 'wb+')
34
- end
35
-
36
- it "does nothing when no X-Sendfile-Type header present" do
37
- request do |response|
38
- response.must_be :ok?
39
- response.body.must_equal 'Hello World'
40
- response.headers.wont_include 'X-Sendfile'
41
- end
42
- end
43
-
44
- it "sets X-Sendfile response header and discards body" do
45
- request 'HTTP_X_SENDFILE_TYPE' => 'X-Sendfile' do |response|
46
- response.must_be :ok?
47
- response.body.must_be :empty?
48
- response.headers['Content-Length'].must_equal '0'
49
- response.headers['X-Sendfile'].must_equal File.join(Dir.tmpdir, "rack_sendfile")
50
- end
51
- end
52
-
53
- it "sets X-Lighttpd-Send-File response header and discards body" do
54
- request 'HTTP_X_SENDFILE_TYPE' => 'X-Lighttpd-Send-File' do |response|
55
- response.must_be :ok?
56
- response.body.must_be :empty?
57
- response.headers['Content-Length'].must_equal '0'
58
- response.headers['X-Lighttpd-Send-File'].must_equal File.join(Dir.tmpdir, "rack_sendfile")
59
- end
60
- end
61
-
62
- it "sets X-Accel-Redirect response header and discards body" do
63
- headers = {
64
- 'HTTP_X_SENDFILE_TYPE' => 'X-Accel-Redirect',
65
- 'HTTP_X_ACCEL_MAPPING' => "#{Dir.tmpdir}/=/foo/bar/"
66
- }
67
- request headers do |response|
68
- response.must_be :ok?
69
- response.body.must_be :empty?
70
- response.headers['Content-Length'].must_equal '0'
71
- response.headers['X-Accel-Redirect'].must_equal '/foo/bar/rack_sendfile'
72
- end
73
- end
74
-
75
- it 'writes to rack.error when no X-Accel-Mapping is specified' do
76
- request 'HTTP_X_SENDFILE_TYPE' => 'X-Accel-Redirect' do |response|
77
- response.must_be :ok?
78
- response.body.must_equal 'Hello World'
79
- response.headers.wont_include 'X-Accel-Redirect'
80
- response.errors.must_include 'X-Accel-Mapping'
81
- end
82
- end
83
-
84
- it 'does nothing when body does not respond to #to_path' do
85
- request({'HTTP_X_SENDFILE_TYPE' => 'X-Sendfile'}, ['Not a file...']) do |response|
86
- response.body.must_equal 'Not a file...'
87
- response.headers.wont_include 'X-Sendfile'
88
- end
89
- end
90
-
91
- it "sets X-Accel-Redirect response header and discards body when initialized with multiple mappings" do
92
- begin
93
- dir1 = Dir.mktmpdir
94
- dir2 = Dir.mktmpdir
95
-
96
- first_body = open_file(File.join(dir1, 'rack_sendfile'))
97
- first_body.puts 'hello world'
98
-
99
- second_body = open_file(File.join(dir2, 'rack_sendfile'))
100
- second_body.puts 'goodbye world'
101
-
102
- mappings = [
103
- ["#{dir1}/", '/foo/bar/'],
104
- ["#{dir2}/", '/wibble/']
105
- ]
106
-
107
- request({'HTTP_X_SENDFILE_TYPE' => 'X-Accel-Redirect'}, first_body, mappings) do |response|
108
- response.must_be :ok?
109
- response.body.must_be :empty?
110
- response.headers['Content-Length'].must_equal '0'
111
- response.headers['X-Accel-Redirect'].must_equal '/foo/bar/rack_sendfile'
112
- end
113
-
114
- request({'HTTP_X_SENDFILE_TYPE' => 'X-Accel-Redirect'}, second_body, mappings) do |response|
115
- response.must_be :ok?
116
- response.body.must_be :empty?
117
- response.headers['Content-Length'].must_equal '0'
118
- response.headers['X-Accel-Redirect'].must_equal '/wibble/rack_sendfile'
119
- end
120
- ensure
121
- FileUtils.remove_entry_secure dir1
122
- FileUtils.remove_entry_secure dir2
123
- end
124
- end
125
- end
@@ -1,193 +0,0 @@
1
- require 'minitest/autorun'
2
- require 'rack'
3
- require 'rack/server'
4
- require 'tempfile'
5
- require 'socket'
6
- require 'open-uri'
7
-
8
- module Minitest::Spec::DSL
9
- alias :should :it
10
- end
11
-
12
- describe Rack::Server do
13
- SPEC_ARGV = []
14
-
15
- before { SPEC_ARGV[0..-1] = [] }
16
-
17
- def app
18
- lambda { |env| [200, {'Content-Type' => 'text/plain'}, ['success']] }
19
- end
20
-
21
- def with_stderr
22
- old, $stderr = $stderr, StringIO.new
23
- yield $stderr
24
- ensure
25
- $stderr = old
26
- end
27
-
28
- it "overrides :config if :app is passed in" do
29
- server = Rack::Server.new(:app => "FOO")
30
- server.app.must_equal "FOO"
31
- end
32
-
33
- it "prefer to use :builder when it is passed in" do
34
- server = Rack::Server.new(:builder => "run lambda { |env| [200, {'Content-Type' => 'text/plain'}, ['success']] }")
35
- server.app.class.must_equal Proc
36
- Rack::MockRequest.new(server.app).get("/").body.to_s.must_equal 'success'
37
- end
38
-
39
- it "allow subclasses to override middleware" do
40
- server = Class.new(Rack::Server).class_eval { def middleware; Hash.new [] end; self }
41
- server.middleware['deployment'].wont_equal []
42
- server.new(:app => 'foo').middleware['deployment'].must_equal []
43
- end
44
-
45
- it "allow subclasses to override default middleware" do
46
- server = Class.new(Rack::Server).instance_eval { def default_middleware_by_environment; Hash.new [] end; self }
47
- server.middleware['deployment'].must_equal []
48
- server.new(:app => 'foo').middleware['deployment'].must_equal []
49
- end
50
-
51
- it "only provide default middleware for development and deployment environments" do
52
- Rack::Server.default_middleware_by_environment.keys.sort.must_equal %w(deployment development)
53
- end
54
-
55
- it "always return an empty array for unknown environments" do
56
- server = Rack::Server.new(:app => 'foo')
57
- server.middleware['production'].must_equal []
58
- end
59
-
60
- it "not include Rack::Lint in deployment environment" do
61
- server = Rack::Server.new(:app => 'foo')
62
- server.middleware['deployment'].flatten.wont_include Rack::Lint
63
- end
64
-
65
- it "not include Rack::ShowExceptions in deployment environment" do
66
- server = Rack::Server.new(:app => 'foo')
67
- server.middleware['deployment'].flatten.wont_include Rack::ShowExceptions
68
- end
69
-
70
- it "include Rack::TempfileReaper in deployment environment" do
71
- server = Rack::Server.new(:app => 'foo')
72
- server.middleware['deployment'].flatten.must_include Rack::TempfileReaper
73
- end
74
-
75
- it "support CGI" do
76
- begin
77
- o, ENV["REQUEST_METHOD"] = ENV["REQUEST_METHOD"], 'foo'
78
- server = Rack::Server.new(:app => 'foo')
79
- server.server.name =~ /CGI/
80
- Rack::Server.logging_middleware.call(server).must_be_nil
81
- ensure
82
- ENV['REQUEST_METHOD'] = o
83
- end
84
- end
85
-
86
- it "be quiet if said so" do
87
- server = Rack::Server.new(:app => "FOO", :quiet => true)
88
- Rack::Server.logging_middleware.call(server).must_be_nil
89
- end
90
-
91
- it "use a full path to the pidfile" do
92
- # avoids issues with daemonize chdir
93
- opts = Rack::Server.new.send(:parse_options, %w[--pid testing.pid])
94
- opts[:pid].must_equal ::File.expand_path('testing.pid')
95
- end
96
-
97
- it "get options from ARGV" do
98
- SPEC_ARGV[0..-1] = ['--debug', '-sthin', '--env', 'production']
99
- server = Rack::Server.new
100
- server.options[:debug].must_equal true
101
- server.options[:server].must_equal 'thin'
102
- server.options[:environment].must_equal 'production'
103
- end
104
-
105
- it "only override non-passed options from parsed .ru file" do
106
- builder_file = File.join(File.dirname(__FILE__), 'builder', 'options.ru')
107
- SPEC_ARGV[0..-1] = ['--debug', '-sthin', '--env', 'production', builder_file]
108
- server = Rack::Server.new
109
- server.app # force .ru file to be parsed
110
-
111
- server.options[:debug].must_equal true
112
- server.options[:server].must_equal 'thin'
113
- server.options[:environment].must_equal 'production'
114
- server.options[:Port].must_equal '2929'
115
- end
116
-
117
- it "run a server" do
118
- pidfile = Tempfile.open('pidfile') { |f| break f }
119
- FileUtils.rm pidfile.path
120
- server = Rack::Server.new(
121
- :app => app,
122
- :environment => 'none',
123
- :pid => pidfile.path,
124
- :Port => TCPServer.open('127.0.0.1', 0){|s| s.addr[1] },
125
- :Host => '127.0.0.1',
126
- :Logger => WEBrick::Log.new(nil, WEBrick::BasicLog::WARN),
127
- :AccessLog => [],
128
- :daemonize => false,
129
- :server => 'webrick'
130
- )
131
- t = Thread.new { server.start { |s| Thread.current[:server] = s } }
132
- t.join(0.01) until t[:server] && t[:server].status != :Stop
133
- body = open("http://127.0.0.1:#{server.options[:Port]}/") { |f| f.read }
134
- body.must_equal 'success'
135
-
136
- Process.kill(:INT, $$)
137
- t.join
138
- open(pidfile.path) { |f| f.read.must_equal $$.to_s }
139
- end
140
-
141
- it "check pid file presence and running process" do
142
- pidfile = Tempfile.open('pidfile') { |f| f.write($$); break f }.path
143
- server = Rack::Server.new(:pid => pidfile)
144
- server.send(:pidfile_process_status).must_equal :running
145
- end
146
-
147
- it "check pid file presence and dead process" do
148
- dead_pid = `echo $$`.to_i
149
- pidfile = Tempfile.open('pidfile') { |f| f.write(dead_pid); break f }.path
150
- server = Rack::Server.new(:pid => pidfile)
151
- server.send(:pidfile_process_status).must_equal :dead
152
- end
153
-
154
- it "check pid file presence and exited process" do
155
- pidfile = Tempfile.open('pidfile') { |f| break f }.path
156
- ::File.delete(pidfile)
157
- server = Rack::Server.new(:pid => pidfile)
158
- server.send(:pidfile_process_status).must_equal :exited
159
- end
160
-
161
- it "check pid file presence and not owned process" do
162
- pidfile = Tempfile.open('pidfile') { |f| f.write(1); break f }.path
163
- server = Rack::Server.new(:pid => pidfile)
164
- server.send(:pidfile_process_status).must_equal :not_owned
165
- end
166
-
167
- it "not write pid file when it is created after check" do
168
- pidfile = Tempfile.open('pidfile') { |f| break f }.path
169
- ::File.delete(pidfile)
170
- server = Rack::Server.new(:pid => pidfile)
171
- ::File.open(pidfile, 'w') { |f| f.write(1) }
172
- with_stderr do |err|
173
- lambda { server.send(:write_pid) }.must_raise SystemExit
174
- err.rewind
175
- output = err.read
176
- output.must_match(/already running/)
177
- output.must_include pidfile
178
- end
179
- end
180
-
181
- it "inform the user about existing pidfiles with running processes" do
182
- pidfile = Tempfile.open('pidfile') { |f| f.write(1); break f }.path
183
- server = Rack::Server.new(:pid => pidfile)
184
- with_stderr do |err|
185
- lambda { server.start }.must_raise SystemExit
186
- err.rewind
187
- output = err.read
188
- output.must_match(/already running/)
189
- output.must_include pidfile
190
- end
191
- end
192
-
193
- end