mongrel2 0.52.1 → 0.52.2

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.
@@ -1,3 +1,13 @@
1
+ == v0.52.2 [2019-04-24] Michael Granger <ged@FaerieMUD.org>
2
+
3
+ Bugfixes:
4
+
5
+ - Don't set linger on the Connection sockets until they're closing
6
+ - Defer creation of the reactor in the handler until it's #run
7
+ - Add #extended_reply? predicate to Mongrel2::Request for cases where
8
+ it's used as a response too
9
+
10
+
1
11
  == v0.52.1 [2018-07-23] Michael Granger <ged@FaerieMUD.org>
2
12
 
3
13
  Bugfixes:
@@ -22,10 +22,10 @@ module Mongrel2
22
22
  abort "\n\n>>> Mongrel2 requires Ruby 2.2 or later. <<<\n\n" if RUBY_VERSION < '2.2.0'
23
23
 
24
24
  # Library version constant
25
- VERSION = '0.52.1'
25
+ VERSION = '0.52.2'
26
26
 
27
27
  # Version-control revision constant
28
- REVISION = %q$Revision: 476c62e8a8f0 $
28
+ REVISION = %q$Revision$
29
29
 
30
30
 
31
31
  require 'mongrel2/constants'
@@ -68,12 +68,10 @@ class Mongrel2::Connection
68
68
  def connect
69
69
  self.log.info "Connecting PULL request socket (%s)" % [ self.sub_addr ]
70
70
  @request_sock = CZTop::Socket::PULL.new
71
- @request_sock.options.linger = 0
72
71
  @request_sock.connect( self.sub_addr )
73
72
 
74
73
  self.log.info "Connecting PUB response socket (%s)" % [ self.pub_addr ]
75
74
  @response_sock = CZTop::Socket::PUB.new
76
- @response_sock.options.linger = 0
77
75
  @response_sock.connect( self.pub_addr )
78
76
  end
79
77
 
@@ -197,8 +195,14 @@ class Mongrel2::Connection
197
195
  def close
198
196
  return if self.closed?
199
197
  self.closed = true
200
- @request_sock.close if @request_sock
201
- @response_sock.close if @response_sock
198
+ if @request_sock
199
+ @request_sock.options.linger = 0
200
+ @request_sock.close
201
+ end
202
+ if @response_sock
203
+ @response_sock.options.linger = 0
204
+ @response_sock.close
205
+ end
202
206
  end
203
207
 
204
208
 
@@ -141,10 +141,10 @@ class Mongrel2::Handler
141
141
  def initialize( app_id, send_spec, recv_spec ) # :notnew:
142
142
  super() # To the signal handler mixin
143
143
 
144
- @app_id = app_id
144
+ @app_id = app_id
145
145
 
146
- @conn = Mongrel2::Connection.new( app_id, send_spec, recv_spec )
147
- @reactor = CZTop::Reactor.new
146
+ @conn = Mongrel2::Connection.new( app_id, send_spec, recv_spec )
147
+ @reactor = nil
148
148
  end
149
149
 
150
150
 
@@ -162,13 +162,14 @@ class Mongrel2::Handler
162
162
 
163
163
  ##
164
164
  # The CZTop::Reactor that manages IO
165
- attr_reader :reactor
165
+ attr_accessor :reactor
166
166
 
167
167
 
168
168
  ### Run the handler.
169
169
  def run
170
170
  self.log.info "Starting up %p" % [ self ]
171
171
 
172
+ self.reactor = CZTop::Reactor.new
172
173
  self.reactor.register( @conn.request_sock, :read, &self.method(:on_socket_event) )
173
174
  self.with_signal_handler( self.reactor, *QUEUE_SIGS ) do
174
175
  self.start_accepting_requests
@@ -232,6 +233,8 @@ class Mongrel2::Handler
232
233
  ### Restart the handler. You should override this if you want to re-establish
233
234
  ### database connections, flush caches, or other restart-ey stuff.
234
235
  def restart
236
+ raise "can't restart: not running" unless self.reactor
237
+
235
238
  self.log.info "Restarting"
236
239
  if (( old_conn = @conn ))
237
240
  self.reactor.unregister( old_conn.request_sock )
@@ -248,6 +248,12 @@ class Mongrel2::Request
248
248
  end
249
249
 
250
250
 
251
+ ### Indicate that a request is never an extended reply.
252
+ def extended_reply?
253
+ return false
254
+ end
255
+
256
+
251
257
  #
252
258
  # :section: Introspection Methods
253
259
  #
@@ -26,42 +26,49 @@ describe Mongrel2::Config::Directory, :db do
26
26
  expect( @dir ).to be_valid()
27
27
  end
28
28
 
29
+
29
30
  it "isn't valid if it doesn't have a base" do
30
31
  @dir.base = nil
31
32
  expect( @dir ).to_not be_valid()
32
33
  expect( @dir.errors.full_messages.first ).to match( /missing or nil/i )
33
34
  end
34
35
 
36
+
35
37
  it "isn't valid when its base starts with '/'" do
36
38
  @dir.base = '/var/www/public/'
37
39
  expect( @dir ).to_not be_valid()
38
40
  expect( @dir.errors.full_messages.first ).to match( %r{shouldn't start with '/'}i )
39
41
  end
40
42
 
43
+
41
44
  it "isn't valid when its base doesn't end with '/'" do
42
45
  @dir.base = 'var/www/public'
43
46
  expect( @dir ).to_not be_valid()
44
47
  expect( @dir.errors.full_messages.first ).to match( %r{must end with '/'}i )
45
48
  end
46
49
 
50
+
47
51
  it "isn't valid if it doesn't have an index file" do
48
52
  @dir.index_file = nil
49
53
  expect( @dir ).to_not be_valid()
50
54
  expect( @dir.errors.full_messages.first ).to match( /must not be nil/i )
51
55
  end
52
56
 
57
+
53
58
  it "isn't valid if it doesn't have a default content-type" do
54
59
  @dir.default_ctype = nil
55
60
  expect( @dir ).to_not be_valid()
56
61
  expect( @dir.errors.full_messages.first ).to match( /must not be nil/i )
57
62
  end
58
63
 
64
+
59
65
  it "isn't valid if its cache TTL is set to a negative value" do
60
66
  @dir.cache_ttl = -5
61
67
  expect( @dir ).to_not be_valid()
62
68
  expect( @dir.errors.full_messages.first ).to match( /not a positive integer/i )
63
69
  end
64
70
 
71
+
65
72
  it "is valid if its cache TTL is set to zero" do
66
73
  @dir.cache_ttl = 0
67
74
  expect( @dir ).to be_valid()
@@ -17,6 +17,7 @@ describe Mongrel2::Config::DSL, :db do
17
17
 
18
18
 
19
19
  describe 'servers' do
20
+
20
21
  it "can generate a default server config using the 'server' declarative" do
21
22
  result = server '965A7196-99BC-46FA-945B-3478AE92BFB5'
22
23
 
@@ -42,6 +43,7 @@ describe Mongrel2::Config::DSL, :db do
42
43
  expect( result.error_log ).to eq( '/var/log/errors' )
43
44
  expect( result.control_port ).to eq( '/var/run/intranet.sock' )
44
45
  end
46
+
45
47
  end
46
48
 
47
49
  describe 'hosts' do
@@ -61,6 +63,7 @@ describe Mongrel2::Config::DSL, :db do
61
63
  expect( host.name ).to eq( 'localhost' )
62
64
  end
63
65
 
66
+
64
67
  it "can add several elaborately-configured hosts to a server via a block" do
65
68
  result = server '965A7196-99BC-46FA-945B-3478AE92BFB5' do
66
69
 
@@ -138,9 +141,9 @@ describe Mongrel2::Config::DSL, :db do
138
141
  expect( host2.routes.first ).to be_a( Mongrel2::Config::Route )
139
142
  end
140
143
 
141
-
142
144
  end
143
145
 
146
+
144
147
  describe 'settings' do
145
148
 
146
149
  before( :all ) do
@@ -151,6 +154,7 @@ describe Mongrel2::Config::DSL, :db do
151
154
  Mongrel2::Config::Setting.dataset.exclude( :id => @ids ).delete
152
155
  end
153
156
 
157
+
154
158
  it "can set the expert tweakable settings en masse" do
155
159
  result = settings(
156
160
  "zeromq.threads" => 8,
@@ -169,6 +173,7 @@ describe Mongrel2::Config::DSL, :db do
169
173
  expect( result[2].value ).to eq( '0666' )
170
174
  end
171
175
 
176
+
172
177
  it "can set a single expert setting" do
173
178
  result = setting "zeromq.threads", 16
174
179
  expect( result ).to be_a( Mongrel2::Config::Setting )
@@ -195,6 +200,7 @@ describe Mongrel2::Config::DSL, :db do
195
200
  expect( result[1].mimetype ).to eq( 'text/x-textile' )
196
201
  end
197
202
 
203
+
198
204
  it "can set a single mimetype mapping" do
199
205
  result = mimetype '.tmpl', 'text/x-inversion-template'
200
206
  expect( result ).to be_a( Mongrel2::Config::Mimetype )
@@ -204,6 +210,7 @@ describe Mongrel2::Config::DSL, :db do
204
210
 
205
211
  end
206
212
 
213
+
207
214
  describe 'filters' do
208
215
 
209
216
  it "can add a filter to a server" do
@@ -216,6 +223,7 @@ describe Mongrel2::Config::DSL, :db do
216
223
  expect( result.filters.first.settings ).to eq( {} )
217
224
  end
218
225
 
226
+
219
227
  it "can add a filter with settings to a server" do
220
228
  result = server '965A7196-99BC-46FA-945B-3478AE92BFB5' do
221
229
  filter '/usr/lib/mongrel2/null.so',
@@ -231,6 +239,7 @@ describe Mongrel2::Config::DSL, :db do
231
239
 
232
240
  end
233
241
 
242
+
234
243
  describe 'xrequests' do
235
244
 
236
245
  it "can add an xrequest to a server" do
@@ -243,6 +252,7 @@ describe Mongrel2::Config::DSL, :db do
243
252
  expect( result.xrequests.first.settings ).to eq( {} )
244
253
  end
245
254
 
255
+
246
256
  it "can add a filter with settings to a server" do
247
257
  result = server '965A7196-99BC-46FA-945B-3478AE92BFB5' do
248
258
  xrequest '/usr/lib/mongrel2/null.so',
@@ -24,7 +24,6 @@ describe Mongrel2::Config::Handler, :db do
24
24
  end
25
25
 
26
26
 
27
-
28
27
  it "is valid if its specs and identities are all valid" do
29
28
  expect( @handler ).to be_valid()
30
29
  end
@@ -36,6 +35,7 @@ describe Mongrel2::Config::Handler, :db do
36
35
  expect( @handler.errors.full_messages.first ).to match( /must not be nil/i )
37
36
  end
38
37
 
38
+
39
39
  it "isn't valid if it doesn't have a recv_spec" do
40
40
  @handler.recv_spec = nil
41
41
  expect( @handler ).to_not be_valid()
@@ -49,6 +49,7 @@ describe Mongrel2::Config::Handler, :db do
49
49
  expect( @handler.errors.full_messages.first ).to match( /not a uri/i )
50
50
  end
51
51
 
52
+
52
53
  it "isn't valid if it doesn't have a valid URL in its recv_spec" do
53
54
  @handler.recv_spec = 'smoke signals'
54
55
  expect( @handler ).to_not be_valid()
@@ -62,6 +63,7 @@ describe Mongrel2::Config::Handler, :db do
62
63
  expect( @handler.errors.full_messages.first ).to match( /invalid 0mq transport/i )
63
64
  end
64
65
 
66
+
65
67
  it "isn't valid if has an unsupported transport in its recv_spec" do
66
68
  @handler.recv_spec = 'inproc://application'
67
69
  expect( @handler ).to_not be_valid()
@@ -75,6 +77,7 @@ describe Mongrel2::Config::Handler, :db do
75
77
  expect( @handler.errors.full_messages.first ).to match( /invalid sender identity/i )
76
78
  end
77
79
 
80
+
78
81
  it "*is* valid if it doesn't have a recv_ident" do
79
82
  @handler.recv_ident = nil
80
83
  expect( @handler ).to be_valid()
@@ -86,17 +89,20 @@ describe Mongrel2::Config::Handler, :db do
86
89
  expect( @handler ).to be_valid()
87
90
  end
88
91
 
92
+
89
93
  it "is valid if it has 'tnetstring' set as the protocol" do
90
94
  @handler.protocol = 'tnetstring'
91
95
  expect( @handler ).to be_valid()
92
96
  end
93
97
 
98
+
94
99
  it "isn't valid if it has an invalid protocol" do
95
100
  @handler.protocol = 'morsecode'
96
101
  expect( @handler ).to_not be_valid()
97
102
  expect( @handler.errors.full_messages.first ).to match( /invalid/i )
98
103
  end
99
104
 
105
+
100
106
  it "isn't valid if its send_spec isn't unique" do
101
107
  dup = @handler.dup
102
108
  @handler.save
@@ -29,6 +29,7 @@ describe Mongrel2::Config::Log, :db do
29
29
  expect( log.how ).to eq( how )
30
30
  end
31
31
 
32
+
32
33
  it "has reasonable defaults for 'where' and 'how'" do
33
34
  what = 'load etc/mongrel2.conf'
34
35
  why = 'updating'
@@ -39,6 +40,7 @@ describe Mongrel2::Config::Log, :db do
39
40
  expect( log.how ).to eq( File.basename( $0 ) )
40
41
  end
41
42
 
43
+
42
44
  describe "an entry" do
43
45
 
44
46
  before( :each ) do
@@ -66,6 +68,7 @@ describe Mongrel2::Config::Log, :db do
66
68
  }x)
67
69
  end
68
70
 
71
+
69
72
  it "stringifies with a reason if it has one" do
70
73
  @log.why = 'Because'
71
74
 
@@ -30,6 +30,7 @@ describe Mongrel2::Config::Route, :db do
30
30
  expect( @route.target ).to eq( dir )
31
31
  end
32
32
 
33
+
33
34
  it "returns a Mongrel2::Config::Proxy if its target_type is 'proxy'" do
34
35
  proxy = Mongrel2::Config::Proxy.create( :addr => '10.2.18.8' )
35
36
 
@@ -39,6 +40,7 @@ describe Mongrel2::Config::Route, :db do
39
40
  expect( @route.target ).to eq( proxy )
40
41
  end
41
42
 
43
+
42
44
  it "returns a Mongrel2::Config::Handler if its target_type is 'handler'" do
43
45
  handler = Mongrel2::Config::Handler.create(
44
46
  :send_ident => TEST_UUID,
@@ -51,6 +53,7 @@ describe Mongrel2::Config::Route, :db do
51
53
  expect( @route.target ).to eq( handler )
52
54
  end
53
55
 
56
+
54
57
  it "raises an exception if its target_type is set to something invalid" do
55
58
  @route.target_type = 'giraffes'
56
59
 
@@ -30,30 +30,35 @@ describe Mongrel2::Config::Server, :db do
30
30
  expect( @server ).to be_valid()
31
31
  end
32
32
 
33
+
33
34
  it "isn't valid if it doesn't have an access_log path" do
34
35
  @server.access_log = nil
35
36
  expect( @server ).to_not be_valid()
36
37
  expect( @server.errors.full_messages.first ).to match( /missing or nil/i )
37
38
  end
38
39
 
40
+
39
41
  it "isn't valid if it doesn't have an error_log path" do
40
42
  @server.error_log = nil
41
43
  expect( @server ).to_not be_valid()
42
44
  expect( @server.errors.full_messages.first ).to match( /missing or nil/i )
43
45
  end
44
46
 
47
+
45
48
  it "isn't valid if it doesn't have an pid_file path" do
46
49
  @server.pid_file = nil
47
50
  expect( @server ).to_not be_valid()
48
51
  expect( @server.errors.full_messages.first ).to match( /missing or nil/i )
49
52
  end
50
53
 
54
+
51
55
  it "isn't valid if it doesn't have a default_host" do
52
56
  @server.default_host = nil
53
57
  expect( @server ).to_not be_valid()
54
58
  expect( @server.errors.full_messages.first ).to match( /missing or nil/i )
55
59
  end
56
60
 
61
+
57
62
  it "isn't valid if it doesn't specify a port" do
58
63
  @server.port = nil
59
64
  expect( @server ).to_not be_valid()
@@ -68,6 +73,7 @@ describe Mongrel2::Config::Server, :db do
68
73
  expect( @server.control_socket_uri ).to eq( 'ipc:///usr/local/www/run/control' )
69
74
  end
70
75
 
76
+
71
77
  it "knows where its control socket is if there is a setting for control_port" do
72
78
  Mongrel2::Config::Setting.dataset.truncate
73
79
  allow( FileTest ).to receive( :socket? ).with( '/usr/local/www/var/run/control.sock' ).
@@ -76,12 +82,14 @@ describe Mongrel2::Config::Server, :db do
76
82
  expect( @server.control_socket_uri ).to eq( 'ipc:///usr/local/www/var/run/control.sock' )
77
83
  end
78
84
 
85
+
79
86
  it "raises an error if the control socket path doesn't point to a UNIX socket" do
80
87
  expect {
81
88
  @server.control_socket
82
89
  }.to raise_error( RuntimeError, /unable to find the socket/i )
83
90
  end
84
91
 
92
+
85
93
  it "can create a Mongrel2::Control for its control port" do
86
94
  Mongrel2::Config::Setting.dataset.truncate
87
95
  allow( FileTest ).to receive( :socket? ).with( '/usr/local/www/run/control' ).
@@ -91,12 +99,14 @@ describe Mongrel2::Config::Server, :db do
91
99
  sock.close
92
100
  end
93
101
 
102
+
94
103
  it "knows what the Pathname of its PID file is" do
95
104
  pidfile = @server.pid_file_path
96
105
  expect( pidfile ).to be_a( Pathname )
97
106
  expect( pidfile.to_s ).to eq( '/run/mongrel2.pid' )
98
107
  end
99
108
 
109
+
100
110
  it "has a predicate that understands the use_ssl value" do
101
111
  expect( @server.use_ssl ).to be_falsey()
102
112
  @server.use_ssl = true
@@ -38,12 +38,14 @@ describe Mongrel2::Config do
38
38
  end
39
39
  end
40
40
 
41
+
41
42
  it "can reset the database handle for the config classes" do
42
43
  db = Mongrel2::Config.in_memory_db
43
44
  Mongrel2::Config.db = db
44
45
  expect( Mongrel2::Config::Directory.db ).to equal( db )
45
46
  end
46
47
 
48
+
47
49
  it "has a convenience method for fetching an Array of all of its configured servers" do
48
50
  Mongrel2::Config.init_database
49
51
  Mongrel2::Config::Server.truncate
@@ -60,6 +62,7 @@ describe Mongrel2::Config do
60
62
  expect( Mongrel2::Config.servers.first.uuid ).to eq( TEST_UUID )
61
63
  end
62
64
 
65
+
63
66
  it "has a convenience method for getting a setting's value" do
64
67
  Mongrel2::Config.init_database
65
68
  Mongrel2::Config::Setting.dataset.truncate
@@ -69,10 +72,12 @@ describe Mongrel2::Config do
69
72
  expect( Mongrel2::Config.settings[ :control_port ] ).to eq( 'ipc://var/run/control.sock' )
70
73
  end
71
74
 
75
+
72
76
  it "can read the configuration schema from a data file" do
73
77
  expect( Mongrel2::Config.load_config_schema ).to match( /create table server/i )
74
78
  end
75
79
 
80
+
76
81
  it "knows whether or not its database has been initialized" do
77
82
  Mongrel2::Config.db = Mongrel2::Config.in_memory_db
78
83
  expect( Mongrel2::Config.database_initialized? ).to be_falsey()
@@ -80,6 +85,7 @@ describe Mongrel2::Config do
80
85
  expect( Mongrel2::Config.database_initialized? ).to be_truthy()
81
86
  end
82
87
 
88
+
83
89
  it "doesn't re-initialize the database if the non-bang version of init_database is used" do
84
90
  Mongrel2::Config.db = Mongrel2::Config.in_memory_db
85
91
  Mongrel2::Config.init_database
@@ -88,22 +94,26 @@ describe Mongrel2::Config do
88
94
  Mongrel2::Config.init_database
89
95
  end
90
96
 
97
+
91
98
  it "can return the path to the config DB as a Pathname if it's pointing at a file" do
92
99
  Mongrel2::Config.db = Sequel.
93
100
  connect( adapter: Mongrel2::Config.sqlite_adapter, database: 'config-spec.sqlite' )
94
101
  expect( Mongrel2::Config.dbname ).to eq( 'config-spec.sqlite' )
95
102
  end
96
103
 
104
+
97
105
  it "returns nil if asked for the pathname to an in-memory database" do
98
106
  Mongrel2::Config.db = Mongrel2::Config.in_memory_db
99
107
  expect( Mongrel2::Config.dbname ).to be_nil()
100
108
  end
101
109
 
110
+
102
111
  describe "Configurability support", :if => defined?( Configurability ) do
103
112
  require 'configurability/behavior'
104
113
 
105
114
  it_should_behave_like "an object with Configurability"
106
115
 
116
+
107
117
  it "uses the 'mongrel2' config section" do
108
118
  expect( Mongrel2::Config.config_key ).to eq( :mongrel2 )
109
119
  end