mongrel2 0.51.0 → 0.52.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/ChangeLog +92 -1
- data/History.rdoc +8 -0
- data/Rakefile +1 -0
- data/lib/mongrel2.rb +2 -2
- data/lib/mongrel2/constants.rb +2 -2
- data/lib/mongrel2/handler.rb +40 -96
- data/lib/mongrel2/websocket.rb +13 -0
- data/spec/helpers.rb +36 -0
- data/spec/mongrel2/connection_spec.rb +19 -5
- data/spec/mongrel2/handler_spec.rb +129 -165
- metadata +17 -3
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 2ed8340c773b16f74e9fdfba40baf608f96c13726fc7cdbe4649c414dcb489fc
|
4
|
+
data.tar.gz: 8079493638f14d5e7158687c9e6b0643934821ebb98af1be174704ae833d4cad
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5f9a258f6eeda490594c2601d9b8f8e4b11473f69dc0cffd4cfb324c4c49f62db8b9d26d8c55153895259fbd773bce0547070613ca931f491efcd055960c3b5c
|
7
|
+
data.tar.gz: 899fddeca183837af436fd89aafbf5bfcf9a64a79f2ae51ba25e0c039a2089bd9b115f7a4add96190596c9cb1e70e46e125e2d166cfaf609ba8c559453429599
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/ChangeLog
CHANGED
@@ -1,8 +1,99 @@
|
|
1
|
+
2018-07-21 Michael Granger <ged@FaerieMUD.org>
|
2
|
+
|
3
|
+
* .gems, Rakefile, lib/mongrel2/handler.rb, lib/mongrel2/websocket.rb,
|
4
|
+
mongrel2.gemspec, spec/helpers.rb, spec/mongrel2/connection_spec.rb,
|
5
|
+
spec/mongrel2/handler_spec.rb:
|
6
|
+
Refactor IO code to use cztop-reactor
|
7
|
+
[d266df105426] [tip]
|
8
|
+
|
9
|
+
2018-05-31 Mahlon E. Smith <mahlon@martini.nu>
|
10
|
+
|
11
|
+
* lib/mongrel2/constants.rb:
|
12
|
+
Update for changes to gem upstream.
|
13
|
+
[667013d5334c]
|
14
|
+
|
15
|
+
2017-11-15 Michael Granger <ged@FaerieMUD.org>
|
16
|
+
|
17
|
+
* .hgtags:
|
18
|
+
Added tag v0.51.0 for changeset 89afed83e6e2
|
19
|
+
[1a6fcd8e3a52]
|
20
|
+
|
21
|
+
* .hgsigs:
|
22
|
+
Added signature for changeset 5c042cae7457
|
23
|
+
[89afed83e6e2] [v0.51.0]
|
24
|
+
|
25
|
+
* cert/ged.pem, certs/ged.pem:
|
26
|
+
Fix the name of and update my gem-signing cert
|
27
|
+
[5c042cae7457]
|
28
|
+
|
29
|
+
* History.rdoc, lib/mongrel2.rb:
|
30
|
+
Bump the minor version, update history.
|
31
|
+
[1a66a960918d]
|
32
|
+
|
33
|
+
* Rakefile, mongrel2.gemspec:
|
34
|
+
Update libxml-ruby dep to the latest
|
35
|
+
[9253c00b0a2f]
|
36
|
+
|
37
|
+
2017-11-08 Michael Granger <ged@FaerieMUD.org>
|
38
|
+
|
39
|
+
* mongrel2.gemspec:
|
40
|
+
Update the gemspec
|
41
|
+
[f1817db64b7b]
|
42
|
+
|
43
|
+
* Manifest.txt:
|
44
|
+
Update the manifest
|
45
|
+
[f69cd800ac94]
|
46
|
+
|
47
|
+
* .ruby-version, .tm_properties, Rakefile, lib/mongrel2/config.rb,
|
48
|
+
lib/mongrel2/constants.rb, mongrel2.gemspec:
|
49
|
+
Support Sequel 5
|
50
|
+
[56a2daf04013]
|
51
|
+
|
52
|
+
* data/mongrel2/config.rb.in:
|
53
|
+
Add config input file
|
54
|
+
[19ce3acb3839]
|
55
|
+
|
56
|
+
2017-07-05 Michael Granger <ged@FaerieMUD.org>
|
57
|
+
|
58
|
+
* .hgtags:
|
59
|
+
Added tag v0.50.2 for changeset 08baa3b61eea
|
60
|
+
[79f113fd0f93]
|
61
|
+
|
62
|
+
* .hgsigs:
|
63
|
+
Added signature for changeset 99ce0d32ae15
|
64
|
+
[08baa3b61eea] [v0.50.2]
|
65
|
+
|
66
|
+
* History.rdoc, lib/mongrel2.rb:
|
67
|
+
Bump the patch version, update history.
|
68
|
+
[99ce0d32ae15]
|
69
|
+
|
70
|
+
* lib/mongrel2/handler.rb:
|
71
|
+
Add missing require to Strelka::Handler.
|
72
|
+
[6ad07a7a7775]
|
73
|
+
|
74
|
+
2017-05-31 Michael Granger <ged@FaerieMUD.org>
|
75
|
+
|
76
|
+
* .hgtags:
|
77
|
+
Added tag v0.50.1 for changeset 181a78ed2587
|
78
|
+
[af48c723c110]
|
79
|
+
|
80
|
+
* .hgsigs:
|
81
|
+
Added signature for changeset d7b71efe6141
|
82
|
+
[181a78ed2587] [v0.50.1]
|
83
|
+
|
84
|
+
* History.rdoc, lib/mongrel2.rb:
|
85
|
+
Bump the patch version, update history.
|
86
|
+
[d7b71efe6141]
|
87
|
+
|
88
|
+
* Rakefile, mongrel2.gemspec:
|
89
|
+
Pin Sequel to 4.45 to avoid breaking changes.
|
90
|
+
[e12627bad969]
|
91
|
+
|
1
92
|
2017-05-31 Mahlon E. Smith <mahlon@martini.nu>
|
2
93
|
|
3
94
|
* lib/mongrel2/handler.rb, spec/mongrel2/handler_spec.rb:
|
4
95
|
Randomize the inproc selfpipe socket name.
|
5
|
-
[6beef2396fd4]
|
96
|
+
[6beef2396fd4]
|
6
97
|
|
7
98
|
2017-05-31 Mahlon E. Smith <mahlon@laika.com>
|
8
99
|
|
data/History.rdoc
CHANGED
data/Rakefile
CHANGED
@@ -26,6 +26,7 @@ hoespec = Hoe.spec 'mongrel2' do
|
|
26
26
|
self.developer 'Michael Granger', 'ged@FaerieMUD.org'
|
27
27
|
|
28
28
|
self.dependency 'cztop', '~> 0.11'
|
29
|
+
self.dependency 'cztop-reactor', '~> 0.3'
|
29
30
|
self.dependency 'libxml-ruby', '~> 3.0'
|
30
31
|
self.dependency 'loggability', '~> 0.12'
|
31
32
|
self.dependency 'sequel', '~> 5.2'
|
data/lib/mongrel2.rb
CHANGED
@@ -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.
|
25
|
+
VERSION = '0.52.0'
|
26
26
|
|
27
27
|
# Version-control revision constant
|
28
|
-
REVISION = %q$Revision:
|
28
|
+
REVISION = %q$Revision: aa458f3f9ca9 $
|
29
29
|
|
30
30
|
|
31
31
|
require 'mongrel2/constants'
|
data/lib/mongrel2/constants.rb
CHANGED
@@ -11,8 +11,8 @@ module Mongrel2::Constants
|
|
11
11
|
# The Pathname of the data directory
|
12
12
|
DATA_DIR = if ENV['MONGREL2_DATADIR']
|
13
13
|
Pathname( ENV['MONGREL2_DATADIR'] )
|
14
|
-
elsif Gem.
|
15
|
-
Pathname( Gem.
|
14
|
+
elsif Gem.loaded_specs[ 'mongrel2' ] && File.exist?( Gem.loaded_specs['mongrel2'].datadir )
|
15
|
+
Pathname( Gem.loaded_specs['mongrel2'].datadir )
|
16
16
|
else
|
17
17
|
Pathname( __FILE__ ).dirname.parent.parent + 'data/mongrel2'
|
18
18
|
end
|
data/lib/mongrel2/handler.rb
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
#encoding: utf-8
|
3
3
|
|
4
4
|
require 'cztop'
|
5
|
+
require 'cztop/reactor'
|
6
|
+
require 'cztop/reactor/signal_handling'
|
5
7
|
require 'securerandom'
|
6
8
|
require 'loggability'
|
7
9
|
|
@@ -85,7 +87,8 @@ require 'mongrel2/websocket'
|
|
85
87
|
#
|
86
88
|
class Mongrel2::Handler
|
87
89
|
extend Loggability
|
88
|
-
include Mongrel2::Constants
|
90
|
+
include Mongrel2::Constants,
|
91
|
+
CZTop::Reactor::SignalHandling
|
89
92
|
|
90
93
|
|
91
94
|
# Loggability API -- set up logging under the 'mongrel2' log host
|
@@ -96,7 +99,7 @@ class Mongrel2::Handler
|
|
96
99
|
QUEUE_SIGS = [
|
97
100
|
:INT, :TERM, :HUP, :USR1,
|
98
101
|
# :TODO: :QUIT, :WINCH, :USR2, :TTIN, :TTOU
|
99
|
-
]
|
102
|
+
] & Signal.list.keys.map( &:to_sym )
|
100
103
|
|
101
104
|
|
102
105
|
### Create an instance of the handler using the config from the database with
|
@@ -136,14 +139,12 @@ class Mongrel2::Handler
|
|
136
139
|
### Create a new instance of the handler with the specified +app_id+, +send_spec+,
|
137
140
|
### and +recv_spec+.
|
138
141
|
def initialize( app_id, send_spec, recv_spec ) # :notnew:
|
142
|
+
super() # To the signal handler mixin
|
143
|
+
|
139
144
|
@app_id = app_id
|
140
145
|
|
141
146
|
@conn = Mongrel2::Connection.new( app_id, send_spec, recv_spec )
|
142
|
-
|
143
|
-
@self_pipe = nil
|
144
|
-
@poller = nil
|
145
|
-
|
146
|
-
Thread.main[:signal_queue] = []
|
147
|
+
@reactor = CZTop::Reactor.new
|
147
148
|
end
|
148
149
|
|
149
150
|
|
@@ -151,31 +152,30 @@ class Mongrel2::Handler
|
|
151
152
|
public
|
152
153
|
######
|
153
154
|
|
155
|
+
##
|
154
156
|
# The handler's Mongrel2::Connection object.
|
155
157
|
attr_reader :conn
|
156
158
|
|
159
|
+
##
|
157
160
|
# The app ID the app was created with
|
158
161
|
attr_reader :app_id
|
159
162
|
|
163
|
+
##
|
164
|
+
# The CZTop::Reactor that manages IO
|
165
|
+
attr_reader :reactor
|
166
|
+
|
160
167
|
|
161
168
|
### Run the handler.
|
162
169
|
def run
|
163
170
|
self.log.info "Starting up %p" % [ self ]
|
164
171
|
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
}
|
170
|
-
|
171
|
-
@poller = CZTop::Poller.new( @conn.request_sock, @self_pipe[:reader] )
|
172
|
-
|
173
|
-
self.set_signal_handlers
|
174
|
-
self.start_accepting_requests
|
172
|
+
self.reactor.register( @conn.request_sock, :read, &self.method(:on_socket_event) )
|
173
|
+
self.with_signal_handler( self.reactor, *QUEUE_SIGS ) do
|
174
|
+
self.start_accepting_requests
|
175
|
+
end
|
175
176
|
|
176
177
|
return self # For chaining
|
177
178
|
ensure
|
178
|
-
self.restore_signal_handlers
|
179
179
|
self.log.info "Done: %p" % [ self ]
|
180
180
|
@conn.close if @conn
|
181
181
|
end
|
@@ -224,7 +224,7 @@ class Mongrel2::Handler
|
|
224
224
|
### Shut down the handler.
|
225
225
|
def shutdown
|
226
226
|
self.log.info "Shutting down."
|
227
|
-
self.
|
227
|
+
self.reactor.stop_polling
|
228
228
|
@conn.close
|
229
229
|
end
|
230
230
|
|
@@ -234,9 +234,9 @@ class Mongrel2::Handler
|
|
234
234
|
def restart
|
235
235
|
self.log.info "Restarting"
|
236
236
|
if (( old_conn = @conn ))
|
237
|
+
self.reactor.unregister( old_conn.request_sock )
|
237
238
|
@conn = @conn.dup
|
238
|
-
|
239
|
-
@poller = CZTop::Poller.new( @conn.request_sock, @self_pipe[:reader] )
|
239
|
+
self.reactor.register( @conn.request_sock, :read, &self.method(:on_socket_event) )
|
240
240
|
|
241
241
|
self.log.debug " conn %p -> %p" % [ old_conn, @conn ]
|
242
242
|
old_conn.close
|
@@ -247,28 +247,20 @@ class Mongrel2::Handler
|
|
247
247
|
### Start a loop, accepting a request and handling it.
|
248
248
|
def start_accepting_requests
|
249
249
|
self.log.info "Starting the request loop."
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
case event.socket
|
254
|
-
when @conn.request_sock
|
255
|
-
req = @conn.receive
|
256
|
-
self.accept_request( req ) unless @conn.closed?
|
257
|
-
when @self_pipe[:reader]
|
258
|
-
@self_pipe[:reader].wait
|
259
|
-
self.process_signal_queue
|
260
|
-
else
|
261
|
-
self.log.warn "Got unhandled poller event: %p" % [ event ]
|
262
|
-
end
|
263
|
-
end
|
264
|
-
rescue Errno::EAGAIN
|
265
|
-
# self.log.debug "Got EAGAIN, retrying."
|
266
|
-
rescue Interrupt
|
267
|
-
# self.log.debug "Got an Interrupt; retrying."
|
268
|
-
end
|
269
|
-
end
|
250
|
+
self.reactor.start_polling( ignore_interrupts: true )
|
251
|
+
end
|
252
|
+
|
270
253
|
|
271
|
-
|
254
|
+
### Reactor callback -- handle an IO event.
|
255
|
+
def on_socket_event( event )
|
256
|
+
if event.readable?
|
257
|
+
req = self.conn.receive
|
258
|
+
self.accept_request( req )
|
259
|
+
elsif event.writable?
|
260
|
+
raise "Request socket became writable?!"
|
261
|
+
else
|
262
|
+
raise "Socket event was neither readable nor writable! (%s)" % [ event ]
|
263
|
+
end
|
272
264
|
end
|
273
265
|
|
274
266
|
|
@@ -379,9 +371,9 @@ class Mongrel2::Handler
|
|
379
371
|
def handle_websocket( request )
|
380
372
|
self.log.warn "Unhandled WEBSOCKET frame (%p)" % [ request.headers.path ]
|
381
373
|
res = request.response
|
382
|
-
res.make_close_frame( WebSocket::CLOSE_POLICY_VIOLATION )
|
383
|
-
self.conn.reply( res)
|
374
|
+
res.make_close_frame( Mongrel2::WebSocket::CLOSE_POLICY_VIOLATION )
|
384
375
|
|
376
|
+
self.conn.reply( res )
|
385
377
|
self.conn.reply_close( request )
|
386
378
|
|
387
379
|
return nil
|
@@ -391,8 +383,8 @@ class Mongrel2::Handler
|
|
391
383
|
### Handle a WebSocket handshake HTTP +request+. If not overridden, this method drops
|
392
384
|
### the connection.
|
393
385
|
def handle_websocket_handshake( handshake )
|
394
|
-
self.log.warn "Unhandled WEBSOCKET_HANDSHAKE request (%p)" % [
|
395
|
-
self.conn.reply_close(
|
386
|
+
self.log.warn "Unhandled WEBSOCKET_HANDSHAKE request (%p)" % [ handshake.headers.path ]
|
387
|
+
self.conn.reply_close( handshake )
|
396
388
|
|
397
389
|
return nil
|
398
390
|
end
|
@@ -401,7 +393,7 @@ class Mongrel2::Handler
|
|
401
393
|
### Handle a disconnect notice from Mongrel2 via the given +request+. Its return value
|
402
394
|
### is ignored.
|
403
395
|
def handle_disconnect( request )
|
404
|
-
self.log.info "
|
396
|
+
self.log.info "Connection %p closed." % [ request.conn_id ]
|
405
397
|
return nil
|
406
398
|
end
|
407
399
|
|
@@ -436,57 +428,9 @@ class Mongrel2::Handler
|
|
436
428
|
# :section: Signal Handling
|
437
429
|
# These methods set up some behavior for starting, restarting, and stopping
|
438
430
|
# your application when a signal is received. If you don't want signals to
|
439
|
-
# be handled, override #
|
431
|
+
# be handled, override #handle_signal with an empty method.
|
440
432
|
#
|
441
433
|
|
442
|
-
### Wake up the handler when a signal needs to be processed.
|
443
|
-
def wake_up
|
444
|
-
$stderr.puts "Waking up the signal handler"
|
445
|
-
@self_pipe[ :writer ].signal( 0 )
|
446
|
-
$stderr.puts "Done sending the wakeup."
|
447
|
-
end
|
448
|
-
|
449
|
-
|
450
|
-
### Set up signal handlers for common signals that will shut down, restart, etc.
|
451
|
-
def set_signal_handlers
|
452
|
-
self.log.debug "Setting up deferred signal handlers."
|
453
|
-
QUEUE_SIGS.each do |sig|
|
454
|
-
Signal.trap( sig ) do
|
455
|
-
Thread.main[:signal_queue] << sig
|
456
|
-
self.wake_up
|
457
|
-
$stderr.puts "Done handling the signal."
|
458
|
-
end
|
459
|
-
end
|
460
|
-
end
|
461
|
-
|
462
|
-
|
463
|
-
### Set all signal handlers to ignore.
|
464
|
-
def ignore_signals
|
465
|
-
self.log.debug "Ignoring signals."
|
466
|
-
QUEUE_SIGS.each do |sig|
|
467
|
-
Signal.trap( sig, :IGNORE )
|
468
|
-
end
|
469
|
-
end
|
470
|
-
|
471
|
-
|
472
|
-
### Set the signal handlers back to their defaults.
|
473
|
-
def restore_signal_handlers
|
474
|
-
self.log.debug "Restoring default signal handlers."
|
475
|
-
QUEUE_SIGS.each do |sig|
|
476
|
-
Signal.trap( sig, :DEFAULT )
|
477
|
-
end
|
478
|
-
end
|
479
|
-
|
480
|
-
|
481
|
-
### Handle any queued signals.
|
482
|
-
def process_signal_queue
|
483
|
-
# Look for any signals that arrived and handle them
|
484
|
-
while sig = Thread.main[:signal_queue].shift
|
485
|
-
self.handle_signal( sig )
|
486
|
-
end
|
487
|
-
end
|
488
|
-
|
489
|
-
|
490
434
|
### Handle signals.
|
491
435
|
def handle_signal( sig )
|
492
436
|
self.log.debug "Handling signal %s" % [ sig ]
|
data/lib/mongrel2/websocket.rb
CHANGED
@@ -463,6 +463,13 @@ module Mongrel2::WebSocket
|
|
463
463
|
end
|
464
464
|
|
465
465
|
|
466
|
+
### Set the :close opcode on this frame and set its status to +statuscode+.
|
467
|
+
def make_close_frame( statuscode=Mongrel2::WebSocket::CLOSE_NORMAL )
|
468
|
+
self.opcode = :close
|
469
|
+
self.set_status( statuscode )
|
470
|
+
end
|
471
|
+
|
472
|
+
|
466
473
|
### Overwrite the frame's payload with a status message based on
|
467
474
|
### +statuscode+.
|
468
475
|
def set_status( statuscode )
|
@@ -622,6 +629,12 @@ module Mongrel2::WebSocket
|
|
622
629
|
end
|
623
630
|
|
624
631
|
|
632
|
+
### Compatibility with Mongrel2::Response.
|
633
|
+
def extended_reply? # :nodoc:
|
634
|
+
return false
|
635
|
+
end
|
636
|
+
|
637
|
+
|
625
638
|
#########
|
626
639
|
protected
|
627
640
|
#########
|
data/spec/helpers.rb
CHANGED
@@ -91,6 +91,13 @@ module Mongrel2::SpecHelpers
|
|
91
91
|
end
|
92
92
|
|
93
93
|
|
94
|
+
### Make a Mongrel2::Request from the specified +opts+ and return it.
|
95
|
+
def make_request_object( opts={} )
|
96
|
+
data = make_request( opts )
|
97
|
+
return Mongrel2::Request.parse( data )
|
98
|
+
end
|
99
|
+
|
100
|
+
|
94
101
|
### Make a new-style (TNetstring headers) raw Mongrel2 request from the specified +opts+
|
95
102
|
### and return it as a String.
|
96
103
|
def make_tn_request( opts={} )
|
@@ -135,6 +142,13 @@ module Mongrel2::SpecHelpers
|
|
135
142
|
end
|
136
143
|
|
137
144
|
|
145
|
+
### Make a Mongrel2::JSONRequest from the specified +opts+ and return it.
|
146
|
+
def make_json_request_object( opts={} )
|
147
|
+
data = make_json_request( opts )
|
148
|
+
return Mongrel2::Request.parse( data )
|
149
|
+
end
|
150
|
+
|
151
|
+
|
138
152
|
### Make a Mongrel2 request for an XML route.
|
139
153
|
def make_xml_request( opts={} )
|
140
154
|
opts = TEST_XML_REQUEST_OPTS.merge( opts )
|
@@ -158,6 +172,13 @@ module Mongrel2::SpecHelpers
|
|
158
172
|
end
|
159
173
|
|
160
174
|
|
175
|
+
### Make a Mongrel2::XMLRequest from the specified +opts+ and return it.
|
176
|
+
def make_xml_request_object( opts={} )
|
177
|
+
data = make_xml_request( opts )
|
178
|
+
return Mongrel2::Request.parse( data )
|
179
|
+
end
|
180
|
+
|
181
|
+
|
161
182
|
### Make a Mongrel2 handshake request for a WebSocket route.
|
162
183
|
def make_websocket_handshake( opts={} )
|
163
184
|
opts = TEST_WEBSOCKET_REQUEST_OPTS.merge( opts )
|
@@ -180,6 +201,14 @@ module Mongrel2::SpecHelpers
|
|
180
201
|
end
|
181
202
|
|
182
203
|
|
204
|
+
### Make a Mongrel2::WebSocket::ClientHandshake from the specified +opts+ and
|
205
|
+
### return it.
|
206
|
+
def make_websocket_handshake_object( opts={} )
|
207
|
+
data = make_websocket_handshake( opts )
|
208
|
+
return Mongrel2::Request.parse( data )
|
209
|
+
end
|
210
|
+
|
211
|
+
|
183
212
|
### Make a Mongrel2 frame for a WebSocket route.
|
184
213
|
def make_websocket_frame( opts={} )
|
185
214
|
opts = TEST_WEBSOCKET_REQUEST_OPTS.merge( opts )
|
@@ -201,6 +230,13 @@ module Mongrel2::SpecHelpers
|
|
201
230
|
return data.encode( 'binary' )
|
202
231
|
end
|
203
232
|
|
233
|
+
|
234
|
+
### Make a Mongrel2::WebSocket::Frame from the specified +opts+ and return it.
|
235
|
+
def make_websocket_frame_object( opts={} )
|
236
|
+
data = make_websocket_frame( opts )
|
237
|
+
return Mongrel2::Request.parse( data )
|
238
|
+
end
|
239
|
+
|
204
240
|
end
|
205
241
|
|
206
242
|
|
@@ -14,9 +14,6 @@ require 'mongrel2/connection'
|
|
14
14
|
describe Mongrel2::Connection do
|
15
15
|
include Mongrel2::Config::DSL
|
16
16
|
|
17
|
-
before( :all ) do
|
18
|
-
end
|
19
|
-
|
20
17
|
# Ensure 0MQ never actually gets called
|
21
18
|
before( :each ) do
|
22
19
|
@conn = Mongrel2::Connection.new( TEST_UUID, TEST_SEND_SPEC, TEST_RECV_SPEC )
|
@@ -28,6 +25,7 @@ describe Mongrel2::Connection do
|
|
28
25
|
expect( @conn.instance_variable_get( :@response_sock ) ).to be_nil()
|
29
26
|
end
|
30
27
|
|
28
|
+
|
31
29
|
it "connects to the endpoints specified on demand" do
|
32
30
|
request_sock = double( "request socket", options: OpenStruct.new )
|
33
31
|
response_sock = double( "response socket", options: OpenStruct.new )
|
@@ -45,10 +43,12 @@ describe Mongrel2::Connection do
|
|
45
43
|
expect( @conn.response_sock ).to eq( response_sock )
|
46
44
|
end
|
47
45
|
|
46
|
+
|
48
47
|
it "stringifies as a description of the appid and both sockets" do
|
49
48
|
expect( @conn.to_s ).to eq( "{#{TEST_UUID}} #{TEST_SEND_SPEC} <-> #{TEST_RECV_SPEC}" )
|
50
49
|
end
|
51
50
|
|
51
|
+
|
52
52
|
context "after a connection has been established" do
|
53
53
|
|
54
54
|
before( :each ) do
|
@@ -69,6 +69,7 @@ describe Mongrel2::Connection do
|
|
69
69
|
@conn.close
|
70
70
|
end
|
71
71
|
|
72
|
+
|
72
73
|
it "raises an exception if asked to fetch data after being closed" do
|
73
74
|
allow( @request_sock ).to receive( :close )
|
74
75
|
allow( @response_sock ).to receive( :close )
|
@@ -80,6 +81,7 @@ describe Mongrel2::Connection do
|
|
80
81
|
}.to raise_error( Mongrel2::ConnectionError, /operation on closed connection/i )
|
81
82
|
end
|
82
83
|
|
84
|
+
|
83
85
|
it "doesn't keep its request and response sockets when duped" do
|
84
86
|
request_sock2 = double( "request socket", :options => OpenStruct.new, :connect => nil )
|
85
87
|
response_sock2 = double( "response socket", :options => OpenStruct.new, :connect => nil )
|
@@ -92,6 +94,7 @@ describe Mongrel2::Connection do
|
|
92
94
|
expect( duplicate.response_sock ).to eq( response_sock2 )
|
93
95
|
end
|
94
96
|
|
97
|
+
|
95
98
|
it "doesn't keep its closed state when duped" do
|
96
99
|
expect( @request_sock ).to receive( :close )
|
97
100
|
expect( @response_sock ).to receive( :close )
|
@@ -102,22 +105,26 @@ describe Mongrel2::Connection do
|
|
102
105
|
expect( duplicate ).to_not be_closed()
|
103
106
|
end
|
104
107
|
|
108
|
+
|
105
109
|
it "can read raw request messages off of the request_sock" do
|
106
110
|
expect( @request_sock ).to receive( :receive ).and_return( CZTop::Message.new( "the data" ) )
|
107
111
|
expect( @conn.recv ).to eq( "the data" )
|
108
112
|
end
|
109
113
|
|
114
|
+
|
110
115
|
it "can read request messages off of the request_sock as Mongrel2::Request objects" do
|
111
|
-
|
112
|
-
expect( @request_sock ).to receive( :receive ).and_return( CZTop::Message.new(
|
116
|
+
req = make_request()
|
117
|
+
expect( @request_sock ).to receive( :receive ).and_return( CZTop::Message.new(req) )
|
113
118
|
expect( @conn.receive ).to be_a( Mongrel2::Request )
|
114
119
|
end
|
115
120
|
|
121
|
+
|
116
122
|
it "can write raw response messages with a TNetString header onto the response_sock" do
|
117
123
|
expect( @response_sock ).to receive( :<< ).with( "#{TEST_UUID} 1:8, the data" )
|
118
124
|
@conn.send( TEST_UUID, 8, "the data" )
|
119
125
|
end
|
120
126
|
|
127
|
+
|
121
128
|
it "can write Mongrel2::Responses to the response_sock" do
|
122
129
|
expect( @response_sock ).to receive( :<< ).with( "#{TEST_UUID} 1:8, the data" )
|
123
130
|
|
@@ -125,30 +132,35 @@ describe Mongrel2::Connection do
|
|
125
132
|
@conn.reply( response )
|
126
133
|
end
|
127
134
|
|
135
|
+
|
128
136
|
it "can write raw response messages to more than one conn_id at the same time" do
|
129
137
|
expect( @response_sock ).to receive( :<< ).
|
130
138
|
with( "#{TEST_UUID} 15:8 16 44 45 1833, the data" )
|
131
139
|
@conn.broadcast( TEST_UUID, [8, 16, 44, 45, 1833], 'the data' )
|
132
140
|
end
|
133
141
|
|
142
|
+
|
134
143
|
it "can write raw response messages to more than one conn_id at the same time" do
|
135
144
|
expect( @response_sock ).to receive( :<< ).
|
136
145
|
with( "#{TEST_UUID} 15:8 16 44 45 1833, the data" )
|
137
146
|
@conn.broadcast( TEST_UUID, [8, 16, 44, 45, 1833], 'the data' )
|
138
147
|
end
|
139
148
|
|
149
|
+
|
140
150
|
it "can write an extended response message" do
|
141
151
|
expect( @response_sock ).to receive( :<< ).
|
142
152
|
with( "#{TEST_UUID} 3:X 8, 27:8:sendfile,12:the_data.txt,]" )
|
143
153
|
@conn.send_extended( TEST_UUID, 8, :sendfile, "the_data.txt" )
|
144
154
|
end
|
145
155
|
|
156
|
+
|
146
157
|
it "can broadcast an extended response message" do
|
147
158
|
expect( @response_sock ).to receive( :<< ).
|
148
159
|
with( "#{TEST_UUID} 9:X 8 16 32, 27:8:sendfile,12:the_data.txt,]" )
|
149
160
|
@conn.broadcast_extended( TEST_UUID, [8,16,32], :sendfile, "the_data.txt" )
|
150
161
|
end
|
151
162
|
|
163
|
+
|
152
164
|
it "can write a Mongrel2::Response with extended reply" do
|
153
165
|
expect( @response_sock ).to receive( :<< ).
|
154
166
|
with( "#{TEST_UUID} 1:8, " )
|
@@ -162,6 +174,7 @@ describe Mongrel2::Connection do
|
|
162
174
|
@conn.reply( response )
|
163
175
|
end
|
164
176
|
|
177
|
+
|
165
178
|
it "can tell the connection a request or a response was from to close" do
|
166
179
|
expect( @response_sock ).to receive( :<< ).with( "#{TEST_UUID} 1:8, " )
|
167
180
|
|
@@ -169,6 +182,7 @@ describe Mongrel2::Connection do
|
|
169
182
|
@conn.reply_close( response )
|
170
183
|
end
|
171
184
|
|
185
|
+
|
172
186
|
it "can broadcast a close to multiple connection IDs" do
|
173
187
|
expect( @response_sock ).to receive( :<< ).with( "#{TEST_UUID} 15:8 16 44 45 1833, " )
|
174
188
|
@conn.broadcast_close( TEST_UUID, [8, 16, 44, 45, 1833] )
|
@@ -16,48 +16,9 @@ require 'mongrel2/handler'
|
|
16
16
|
|
17
17
|
describe Mongrel2::Handler, :db do
|
18
18
|
|
19
|
-
# Make a handler class for testing
|
20
|
-
|
21
|
-
|
22
|
-
def initialize( * )
|
23
|
-
@transactions = {}
|
24
|
-
super
|
25
|
-
end
|
26
|
-
|
27
|
-
attr_reader :transactions
|
28
|
-
|
29
|
-
# Overridden to accept one request and shut down
|
30
|
-
def dispatch_request( request )
|
31
|
-
response = super
|
32
|
-
self.transactions[ request ] = response
|
33
|
-
self.shutdown
|
34
|
-
return response
|
35
|
-
end
|
36
|
-
|
37
|
-
end # class OneShotHandler
|
38
|
-
|
39
|
-
|
40
|
-
# Ensure 0MQ never actually gets called
|
41
|
-
before( :each ) do
|
42
|
-
@request_sock = instance_double( CZTop::Socket::PULL, :options => OpenStruct.new, :connect => nil, :close => nil )
|
43
|
-
@response_sock = instance_double( CZTop::Socket::PUB, :options => OpenStruct.new, :connect => nil, :close => nil )
|
44
|
-
@selfpipe_reader = instance_double( CZTop::Socket::PAIR )
|
45
|
-
@selfpipe_writer = instance_double( CZTop::Socket::PAIR )
|
46
|
-
@poller = instance_double( CZTop::Poller )
|
47
|
-
@poller_event = instance_double( CZTop::Poller::Event )
|
48
|
-
|
49
|
-
allow( CZTop::Socket::PULL ).to receive( :new ).and_return( @request_sock )
|
50
|
-
allow( CZTop::Socket::PUB ).to receive( :new ).and_return( @response_sock )
|
51
|
-
allow( CZTop::Socket::PAIR ).to receive( :new ).with( %r|@inproc://signal-handler-\d+-\w{8}| ).
|
52
|
-
and_return( @selfpipe_reader )
|
53
|
-
allow( CZTop::Socket::PAIR ).to receive( :new ).with( %r|>inproc://signal-handler-\d+-\w{8}| ).
|
54
|
-
and_return( @selfpipe_writer )
|
55
|
-
allow( CZTop::Poller ).to receive( :new ).and_return( @poller )
|
56
|
-
|
57
|
-
allow( @poller ).to receive( :wait ).and_return( @poller_event )
|
58
|
-
allow( @poller_event ).to receive( :socket ).and_return( @request_sock )
|
59
|
-
end
|
60
|
-
|
19
|
+
# Make a handler class for testing
|
20
|
+
class TestingHandler < Mongrel2::Handler
|
21
|
+
end # class TestingHandler
|
61
22
|
|
62
23
|
|
63
24
|
context "with a Handler entry in the config database" do
|
@@ -85,30 +46,34 @@ describe Mongrel2::Handler, :db do
|
|
85
46
|
end
|
86
47
|
|
87
48
|
|
88
|
-
it "has a convenience method for instantiating and running a Handler given an "
|
89
|
-
|
49
|
+
it "has a convenience method for instantiating and running a Handler given an application ID" do
|
50
|
+
reactor = instance_double( CZTop::Reactor )
|
51
|
+
expect( CZTop::Reactor ).to receive( :new ).and_return( reactor )
|
52
|
+
expect( reactor ).to receive( :register ).at_least( :once )
|
53
|
+
expect( reactor ).to receive( :unregister ).at_least( :once )
|
54
|
+
expect( reactor ).to receive( :start_polling ).with( ignore_interrupts: true )
|
90
55
|
|
91
|
-
|
92
|
-
expect( @request_sock ).to receive( :receive ).and_return( CZTop::Message.new( req ) )
|
93
|
-
|
94
|
-
res = OneShotHandler.run( TEST_UUID )
|
56
|
+
handler = TestingHandler.run( TEST_UUID )
|
95
57
|
|
96
58
|
# It should have pulled its connection info from the Handler entry in the database
|
97
|
-
expect(
|
98
|
-
expect(
|
99
|
-
expect(
|
59
|
+
expect( handler.conn.app_id ).to eq( TEST_UUID )
|
60
|
+
expect( handler.conn.sub_addr ).to eq( TEST_SEND_SPEC )
|
61
|
+
expect( handler.conn.pub_addr ).to eq( TEST_RECV_SPEC )
|
100
62
|
end
|
101
63
|
|
102
64
|
|
103
|
-
it "knows what handler config corresponds to its" do
|
104
|
-
|
105
|
-
expect(
|
65
|
+
it "knows what handler config corresponds to its app UUID" do
|
66
|
+
reactor = instance_double( CZTop::Reactor )
|
67
|
+
expect( CZTop::Reactor ).to receive( :new ).and_return( reactor )
|
68
|
+
expect( reactor ).to receive( :register ).at_least( :once )
|
69
|
+
expect( reactor ).to receive( :unregister ).at_least( :once )
|
70
|
+
expect( reactor ).to receive( :start_polling ).with( ignore_interrupts: true )
|
106
71
|
|
107
|
-
|
72
|
+
handler = TestingHandler.run( TEST_UUID )
|
108
73
|
|
109
|
-
expect(
|
110
|
-
expect(
|
111
|
-
expect(
|
74
|
+
expect( handler.handler_config ).to be_a( Mongrel2::Config::Handler )
|
75
|
+
expect( handler.handler_config.send_spec ).to eq( TEST_SEND_SPEC )
|
76
|
+
expect( handler.handler_config.recv_spec ).to eq( TEST_RECV_SPEC )
|
112
77
|
end
|
113
78
|
|
114
79
|
end
|
@@ -130,194 +95,189 @@ describe Mongrel2::Handler, :db do
|
|
130
95
|
end
|
131
96
|
|
132
97
|
|
133
|
-
it "
|
134
|
-
|
135
|
-
|
98
|
+
it "responds to HTTP requests with a 204 No Content response by default" do
|
99
|
+
request = make_request_object()
|
100
|
+
handler = TestingHandler.new( TEST_UUID, TEST_SEND_SPEC, TEST_RECV_SPEC )
|
136
101
|
|
137
|
-
|
102
|
+
response = handler.dispatch_request( request )
|
138
103
|
|
139
|
-
expect( res.transactions.size ).to eq( 1 )
|
140
|
-
request, response = res.transactions.first
|
141
|
-
expect( request ).to be_a( Mongrel2::HTTPRequest )
|
142
104
|
expect( response ).to be_a( Mongrel2::HTTPResponse )
|
143
105
|
expect( response.status ).to eq( 204 )
|
144
106
|
end
|
145
107
|
|
146
108
|
|
147
109
|
it "ignores JSON messages by default" do
|
148
|
-
|
149
|
-
|
110
|
+
request = make_json_request_object()
|
111
|
+
handler = TestingHandler.new( TEST_UUID, TEST_SEND_SPEC, TEST_RECV_SPEC )
|
150
112
|
|
151
|
-
|
113
|
+
response = handler.dispatch_request( request )
|
152
114
|
|
153
|
-
expect(
|
154
|
-
request, response = res.transactions.first
|
155
|
-
expect( request ).to be_a( Mongrel2::JSONRequest )
|
156
|
-
expect( response ).to be_nil()
|
115
|
+
expect( response ).to be_nil
|
157
116
|
end
|
158
117
|
|
159
118
|
|
160
119
|
it "dispatches JSON message to the #handle_json method" do
|
161
|
-
|
120
|
+
json_handler_class = Class.new( TestingHandler ) do
|
162
121
|
def handle_json( request )
|
163
122
|
return request.response
|
164
123
|
end
|
165
124
|
end
|
125
|
+
request = make_json_request_object()
|
126
|
+
handler = json_handler_class.new( TEST_UUID, TEST_SEND_SPEC, TEST_RECV_SPEC )
|
166
127
|
|
167
|
-
|
168
|
-
expect( @request_sock ).to receive( :receive ).and_return( CZTop::Message.new( req ) )
|
169
|
-
|
170
|
-
res = json_handler.new( TEST_UUID, TEST_SEND_SPEC, TEST_RECV_SPEC ).run
|
128
|
+
response = handler.dispatch_request( request )
|
171
129
|
|
172
|
-
expect( res.transactions.size ).to eq( 1 )
|
173
|
-
request, response = res.transactions.first
|
174
|
-
expect( request ).to be_a( Mongrel2::JSONRequest )
|
175
130
|
expect( response ).to be_a( Mongrel2::Response )
|
176
131
|
end
|
177
132
|
|
178
133
|
|
179
134
|
it "ignores XML messages by default" do
|
180
|
-
|
181
|
-
|
135
|
+
request = make_xml_request_object()
|
136
|
+
handler = TestingHandler.new( TEST_UUID, TEST_SEND_SPEC, TEST_RECV_SPEC )
|
182
137
|
|
183
|
-
|
138
|
+
response = handler.dispatch_request( request )
|
184
139
|
|
185
|
-
expect(
|
186
|
-
request, response = res.transactions.first
|
187
|
-
expect( request ).to be_a( Mongrel2::XMLRequest )
|
188
|
-
expect( response ).to be_nil()
|
140
|
+
expect( response ).to be_nil
|
189
141
|
end
|
190
142
|
|
191
143
|
|
192
144
|
it "dispatches XML message to the #handle_xml method" do
|
193
|
-
|
145
|
+
xml_handler_class = Class.new( TestingHandler ) do
|
194
146
|
def handle_xml( request )
|
195
147
|
return request.response
|
196
148
|
end
|
197
149
|
end
|
150
|
+
request = make_xml_request_object()
|
151
|
+
handler = xml_handler_class.new( TEST_UUID, TEST_SEND_SPEC, TEST_RECV_SPEC )
|
198
152
|
|
199
|
-
|
200
|
-
expect( @request_sock ).to receive( :receive ).and_return( CZTop::Message.new( req ) )
|
201
|
-
|
202
|
-
res = xml_handler.new( TEST_UUID, TEST_SEND_SPEC, TEST_RECV_SPEC ).run
|
153
|
+
response = handler.dispatch_request( request )
|
203
154
|
|
204
|
-
expect( res.transactions.size ).to eq( 1 )
|
205
|
-
request, response = res.transactions.first
|
206
|
-
expect( request ).to be_a( Mongrel2::XMLRequest )
|
207
155
|
expect( response ).to be_a( Mongrel2::Response )
|
208
156
|
end
|
209
157
|
|
210
158
|
|
159
|
+
it "drops the connection on websocket opening handshakes by default" do
|
160
|
+
request = make_websocket_handshake_object()
|
161
|
+
handler = TestingHandler.new( TEST_UUID, TEST_SEND_SPEC, TEST_RECV_SPEC )
|
162
|
+
|
163
|
+
expect( handler.conn ).to receive( :reply_close ).with( request )
|
164
|
+
|
165
|
+
response = handler.dispatch_request( request )
|
166
|
+
|
167
|
+
expect( response ).to be_nil
|
168
|
+
end
|
169
|
+
|
170
|
+
|
211
171
|
it "dispatches WebSocket opening handshakes to the #handle_websocket_handshake method" do
|
212
|
-
|
172
|
+
ws_handler_class = Class.new( TestingHandler ) do
|
213
173
|
def handle_websocket_handshake( handshake )
|
214
174
|
return handshake.response
|
215
175
|
end
|
216
176
|
end
|
177
|
+
request = make_websocket_handshake_object()
|
178
|
+
handler = ws_handler_class.new( TEST_UUID, TEST_SEND_SPEC, TEST_RECV_SPEC )
|
217
179
|
|
218
|
-
|
219
|
-
expect( @request_sock ).to receive( :receive ).and_return( CZTop::Message.new( req ) )
|
180
|
+
response = handler.dispatch_request( request )
|
220
181
|
|
221
|
-
res = ws_handler.new( TEST_UUID, TEST_SEND_SPEC, TEST_RECV_SPEC ).run
|
222
|
-
|
223
|
-
expect( res.transactions.size ).to eq( 1 )
|
224
|
-
request, response = res.transactions.first
|
225
|
-
expect( request ).to be_a( Mongrel2::WebSocket::ClientHandshake )
|
226
182
|
expect( response ).to be_a( Mongrel2::WebSocket::ServerHandshake )
|
227
183
|
end
|
228
184
|
|
229
185
|
|
230
|
-
it "
|
231
|
-
|
232
|
-
|
233
|
-
return frame.response
|
234
|
-
end
|
235
|
-
end
|
186
|
+
it "directly closes the connection on websocket frames with a protocol violation by default" do
|
187
|
+
request = make_websocket_frame_object()
|
188
|
+
handler = TestingHandler.new( TEST_UUID, TEST_SEND_SPEC, TEST_RECV_SPEC )
|
236
189
|
|
237
|
-
|
238
|
-
expect(
|
190
|
+
expect( handler.conn ).to receive( :reply_close ).with( request )
|
191
|
+
expect( handler.conn ).to receive( :reply ) do |reply|
|
192
|
+
expect( reply ).to be_a( Mongrel2::WebSocket::Frame )
|
193
|
+
expect( reply.opcode ).to eq( :close )
|
194
|
+
reply.payload.rewind
|
195
|
+
expect( reply.payload.read ).to start_with( '1008 ' )
|
196
|
+
end
|
239
197
|
|
240
|
-
|
198
|
+
response = handler.dispatch_request( request )
|
241
199
|
|
242
|
-
expect(
|
243
|
-
request, response = res.transactions.first
|
244
|
-
expect( request ).to be_a( Mongrel2::WebSocket::Frame )
|
245
|
-
expect( response ).to be_a( Mongrel2::WebSocket::Frame )
|
200
|
+
expect( response ).to be_nil
|
246
201
|
end
|
247
202
|
|
248
203
|
|
249
|
-
it "
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
204
|
+
it "dispatches WebSocket protocol frames to the #handle_websocket method" do
|
205
|
+
ws_handler_class = Class.new( TestingHandler ) do
|
206
|
+
def handle_websocket( frame )
|
207
|
+
return frame.response
|
208
|
+
end
|
209
|
+
end
|
210
|
+
request = make_websocket_frame_object()
|
211
|
+
handler = ws_handler_class.new( TEST_UUID, TEST_SEND_SPEC, TEST_RECV_SPEC )
|
255
212
|
|
256
|
-
|
213
|
+
response = handler.dispatch_request( request )
|
257
214
|
|
258
|
-
expect(
|
259
|
-
request, response = res.transactions.first
|
260
|
-
expect( request ).to be_a( Mongrel2::HTTPRequest )
|
261
|
-
expect( response ).to be_a( Mongrel2::HTTPResponse )
|
262
|
-
expect( response.status ).to eq( 204 )
|
215
|
+
expect( response ).to be_a( Mongrel2::WebSocket::Frame )
|
263
216
|
end
|
264
217
|
|
265
218
|
|
266
219
|
it "ignores disconnect notices by default" do
|
267
|
-
|
268
|
-
|
220
|
+
request = make_json_request_object( :path => '@*', :body => {'type' => 'disconnect'} )
|
221
|
+
handler = TestingHandler.new( TEST_UUID, TEST_SEND_SPEC, TEST_RECV_SPEC )
|
269
222
|
|
270
|
-
|
223
|
+
response = handler.dispatch_request( request )
|
271
224
|
|
272
|
-
expect(
|
273
|
-
request, response = res.transactions.first
|
274
|
-
expect( request ).to be_a( Mongrel2::JSONRequest )
|
275
|
-
expect( response ).to be_nil()
|
225
|
+
expect( response ).to be_nil
|
276
226
|
end
|
277
227
|
|
278
228
|
|
279
229
|
it "dispatches disconnect notices to the #handle_disconnect method" do
|
280
|
-
|
230
|
+
disconnect_handler_class = Class.new( TestingHandler ) do
|
231
|
+
def initialize( * )
|
232
|
+
super
|
233
|
+
@handled_disconnect = false
|
234
|
+
end
|
235
|
+
|
236
|
+
attr_reader :handled_disconnect
|
237
|
+
|
281
238
|
def handle_disconnect( request )
|
239
|
+
@handled_disconnect = true
|
282
240
|
self.log.debug "Doing stuff for disconnected connection %d" % [ request.conn_id ]
|
283
241
|
end
|
284
242
|
end
|
243
|
+
request = make_json_request_object( :path => '@*', :body => {'type' => 'disconnect'} )
|
244
|
+
handler = disconnect_handler_class.new( TEST_UUID, TEST_SEND_SPEC, TEST_RECV_SPEC )
|
285
245
|
|
286
|
-
|
287
|
-
expect( @request_sock ).to receive( :receive ).and_return( CZTop::Message.new( req ) )
|
288
|
-
|
289
|
-
res = disconnect_handler.new( TEST_UUID, TEST_SEND_SPEC, TEST_RECV_SPEC ).run
|
246
|
+
response = handler.dispatch_request( request )
|
290
247
|
|
291
|
-
expect(
|
292
|
-
|
293
|
-
expect( request ).to be_a( Mongrel2::JSONRequest )
|
294
|
-
expect( response ).to be_nil()
|
248
|
+
expect( response ).to be_nil
|
249
|
+
expect( handler.handled_disconnect ).to eq( true )
|
295
250
|
end
|
296
251
|
|
297
252
|
|
298
253
|
it "cancels async upload notices by default" do
|
299
|
-
|
300
|
-
|
301
|
-
|
254
|
+
request = make_request_object(
|
255
|
+
'METHOD' => 'POST',
|
256
|
+
headers: {'x-mongrel2-upload-start' => 'uploadfile.XXX'}
|
257
|
+
)
|
258
|
+
handler = TestingHandler.new( TEST_UUID, TEST_SEND_SPEC, TEST_RECV_SPEC )
|
259
|
+
expect( handler.conn ).to receive( :reply_close ).with( request )
|
302
260
|
|
303
|
-
|
261
|
+
response = handler.dispatch_request( request )
|
304
262
|
|
305
|
-
expect(
|
306
|
-
request, response = res.transactions.first
|
307
|
-
expect( response ).to be_nil()
|
263
|
+
expect( response ).to be_nil
|
308
264
|
end
|
309
265
|
|
310
266
|
|
311
267
|
it "re-establishes its connection when told to restart" do
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
268
|
+
handler = TestingHandler.new( TEST_UUID, TEST_SEND_SPEC, TEST_RECV_SPEC )
|
269
|
+
original_conn = handler.conn
|
270
|
+
|
271
|
+
expect( handler.reactor ).to receive( :unregister ).with( original_conn.request_sock )
|
272
|
+
expect( handler.reactor ).to receive( :register ) do |request_sock, mode, &callback|
|
273
|
+
expect( request_sock ).to be_a( CZTop::Socket )
|
274
|
+
expect( request_sock ).to_not equal( original_conn.request_sock )
|
275
|
+
expect( mode ).to eq( :read )
|
276
|
+
end
|
316
277
|
|
317
|
-
|
318
|
-
res.restart
|
278
|
+
handler.restart
|
319
279
|
|
320
|
-
expect(
|
280
|
+
expect( handler.conn ).to_not equal( original_conn )
|
321
281
|
end
|
322
282
|
|
323
283
|
|
@@ -325,14 +285,18 @@ describe Mongrel2::Handler, :db do
|
|
325
285
|
spoolfile = Pathname.new( Dir.tmpdir + '/mongrel2.uskd8l1' )
|
326
286
|
spoolfile.write( "Hi!" )
|
327
287
|
|
328
|
-
|
329
|
-
'
|
330
|
-
|
331
|
-
|
332
|
-
|
288
|
+
request = make_request_object(
|
289
|
+
'METHOD' => 'POST',
|
290
|
+
headers: {
|
291
|
+
'x-mongrel2-upload-start' => spoolfile.basename,
|
292
|
+
'x-mongrel2-upload-done' => spoolfile.basename
|
293
|
+
}
|
294
|
+
)
|
295
|
+
handler = TestingHandler.new( TEST_UUID, TEST_SEND_SPEC, TEST_RECV_SPEC )
|
296
|
+
|
297
|
+
expect( handler.conn ).to receive( :reply ).with( a_kind_of(Mongrel2::Response) )
|
298
|
+
response = handler.accept_request( request )
|
333
299
|
|
334
|
-
res = OneShotHandler.new( TEST_UUID, TEST_SEND_SPEC, TEST_RECV_SPEC ).run
|
335
|
-
request, response = res.transactions.first
|
336
300
|
expect( request.body ).to be_closed
|
337
301
|
expect( spoolfile ).to_not exist
|
338
302
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongrel2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.52.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Granger
|
@@ -35,7 +35,7 @@ cert_chain:
|
|
35
35
|
X0qdrKi+2aZZ0NGuFj9AItBsVmAvkBGIpX4TEKQp5haEbPpmaqO5nIIhV26PXmyT
|
36
36
|
OMKv6pWsoS81vw5KAGBmfX8nht/Py90DQrbRvakATGI=
|
37
37
|
-----END CERTIFICATE-----
|
38
|
-
date:
|
38
|
+
date: 2018-07-21 00:00:00.000000000 Z
|
39
39
|
dependencies:
|
40
40
|
- !ruby/object:Gem::Dependency
|
41
41
|
name: cztop
|
@@ -51,6 +51,20 @@ dependencies:
|
|
51
51
|
- - "~>"
|
52
52
|
- !ruby/object:Gem::Version
|
53
53
|
version: '0.11'
|
54
|
+
- !ruby/object:Gem::Dependency
|
55
|
+
name: cztop-reactor
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0.3'
|
61
|
+
type: :runtime
|
62
|
+
prerelease: false
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0.3'
|
54
68
|
- !ruby/object:Gem::Dependency
|
55
69
|
name: libxml-ruby
|
56
70
|
requirement: !ruby/object:Gem::Requirement
|
@@ -399,7 +413,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
399
413
|
version: '0'
|
400
414
|
requirements: []
|
401
415
|
rubyforge_project:
|
402
|
-
rubygems_version: 2.
|
416
|
+
rubygems_version: 2.7.7
|
403
417
|
signing_key:
|
404
418
|
specification_version: 4
|
405
419
|
summary: Ruby-Mongrel2 is a complete Ruby connector for Mongrel2[http://mongrel2.org/]
|
metadata.gz.sig
CHANGED
Binary file
|