mongrel2 0.25.0 → 0.26.0
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.
- data.tar.gz.sig +0 -0
- data/ChangeLog +51 -1
- data/History.rdoc +6 -0
- data/lib/mongrel2.rb +2 -2
- data/lib/mongrel2/config/handler.rb +9 -0
- data/lib/mongrel2/config/host.rb +18 -0
- data/lib/mongrel2/config/route.rb +17 -0
- data/lib/mongrel2/config/server.rb +25 -3
- data/lib/mongrel2/connection.rb +1 -0
- data/lib/mongrel2/handler.rb +26 -0
- data/lib/mongrel2/httprequest.rb +1 -9
- data/lib/mongrel2/request.rb +12 -4
- data/spec/lib/helpers.rb +2 -0
- data/spec/mongrel2/handler_spec.rb +12 -0
- data/spec/mongrel2/httprequest_spec.rb +0 -14
- data/spec/mongrel2/request_spec.rb +28 -9
- metadata +2 -2
- metadata.gz.sig +0 -0
data.tar.gz.sig
CHANGED
Binary file
|
data/ChangeLog
CHANGED
@@ -1,11 +1,61 @@
|
|
1
|
+
2012-06-26 Michael Granger <ged@FaerieMUD.org>
|
2
|
+
|
3
|
+
* lib/mongrel2/config/handler.rb, lib/mongrel2/config/host.rb,
|
4
|
+
lib/mongrel2/config/route.rb, lib/mongrel2/config/server.rb,
|
5
|
+
lib/mongrel2/connection.rb, lib/mongrel2/handler.rb,
|
6
|
+
lib/mongrel2/httprequest.rb, lib/mongrel2/request.rb,
|
7
|
+
spec/mongrel2/handler_spec.rb, spec/mongrel2/httprequest_spec.rb,
|
8
|
+
spec/mongrel2/request_spec.rb:
|
9
|
+
Fix the async upload body path
|
10
|
+
[782174dcba2e] [tip]
|
11
|
+
|
12
|
+
2012-06-21 Michael Granger <ged@FaerieMUD.org>
|
13
|
+
|
14
|
+
* .hgtags:
|
15
|
+
Added tag v0.25.0 for changeset 79bf424c93cd
|
16
|
+
[0cb15359e25b]
|
17
|
+
|
18
|
+
* .hgsigs:
|
19
|
+
Added signature for changeset 893e0493be04
|
20
|
+
[79bf424c93cd] [v0.25.0]
|
21
|
+
|
22
|
+
* History.rdoc, lib/mongrel2.rb, lib/mongrel2/request.rb:
|
23
|
+
Bumped minor version, updated history
|
24
|
+
[893e0493be04]
|
25
|
+
|
26
|
+
* lib/mongrel2/httprequest.rb, lib/mongrel2/request.rb,
|
27
|
+
lib/mongrel2/response.rb, spec/mongrel2/httprequest_spec.rb,
|
28
|
+
spec/mongrel2/request_spec.rb:
|
29
|
+
Make similar stream adjustments to request as had previously been
|
30
|
+
done to response.
|
31
|
+
[9f061f269db6]
|
32
|
+
|
33
|
+
* spec/mongrel2/response_spec.rb:
|
34
|
+
Fix spelling
|
35
|
+
[7fcb08e469ae]
|
36
|
+
|
37
|
+
* lib/mongrel2/response.rb, spec/mongrel2/response_spec.rb:
|
38
|
+
Don't try to wrap objects that don't support #to_str in a StringIO.
|
39
|
+
[22f3d1c88c37]
|
40
|
+
|
1
41
|
2012-06-20 Michael Granger <ged@FaerieMUD.org>
|
2
42
|
|
43
|
+
* examples/request-dumper.rb, examples/request-dumper.tmpl,
|
44
|
+
lib/mongrel2/connection.rb, lib/mongrel2/request.rb,
|
45
|
+
spec/mongrel2/request_spec.rb:
|
46
|
+
Add support for Content-type charset to Mongrel2::Request.
|
47
|
+
[dae4f2b16ef7]
|
48
|
+
|
49
|
+
* lib/mongrel2/request.rb:
|
50
|
+
Set the body on Mongrel2::Request if constructed with an IO, too.
|
51
|
+
[8721f2abc3c0]
|
52
|
+
|
3
53
|
* examples/async-upload.rb, examples/config.rb,
|
4
54
|
lib/mongrel2/httprequest.rb, lib/mongrel2/request.rb,
|
5
55
|
lib/mongrel2/testing.rb, spec/mongrel2/httprequest_spec.rb,
|
6
56
|
spec/mongrel2/request_spec.rb:
|
7
57
|
Hook up the async uploaded entity body to the request
|
8
|
-
[349c0049a4a1]
|
58
|
+
[349c0049a4a1]
|
9
59
|
|
10
60
|
2012-06-19 Michael Granger <ged@FaerieMUD.org>
|
11
61
|
|
data/History.rdoc
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
== v0.26.0 [2012-06-26] Michael Granger <ged@FaerieMUD.org>
|
2
|
+
|
3
|
+
- Fix the derived path to the async upload body
|
4
|
+
- Add a default async upload handler method that cancels the upload
|
5
|
+
|
6
|
+
|
1
7
|
== v0.25.0 [2012-06-20] Michael Granger <ged@FaerieMUD.org>
|
2
8
|
|
3
9
|
NOTE: This revision contains non-backward-compatible changes to
|
data/lib/mongrel2.rb
CHANGED
@@ -20,10 +20,10 @@ module Mongrel2
|
|
20
20
|
abort "\n\n>>> Mongrel2 requires Ruby 1.9.2 or later. <<<\n\n" if RUBY_VERSION < '1.9.2'
|
21
21
|
|
22
22
|
# Library version constant
|
23
|
-
VERSION = '0.
|
23
|
+
VERSION = '0.26.0'
|
24
24
|
|
25
25
|
# Version-control revision constant
|
26
|
-
REVISION = %q$Revision:
|
26
|
+
REVISION = %q$Revision: c2eac469ca66 $
|
27
27
|
|
28
28
|
|
29
29
|
require 'mongrel2/constants'
|
@@ -16,6 +16,15 @@ class Mongrel2::Config::Handler < Mongrel2::Config( :handler )
|
|
16
16
|
# protocol TEXT DEFAULT 'json');
|
17
17
|
|
18
18
|
|
19
|
+
#
|
20
|
+
# :section: Associations
|
21
|
+
#
|
22
|
+
|
23
|
+
##
|
24
|
+
# The routes[rdoc-ref:Mongrel2::Config::Route] that refer to this Handler
|
25
|
+
one_to_many :routes, :key => :target_id, :conditions => { target_type: 'handler' }
|
26
|
+
|
27
|
+
|
19
28
|
# The list of 0mq transports Mongrel2 can use; "You need to use the
|
20
29
|
# ZeroMQ syntax for configuring them, but this means with one
|
21
30
|
# configuration format you can use handlers that are using UDP, TCP,
|
data/lib/mongrel2/config/host.rb
CHANGED
@@ -13,16 +13,34 @@ class Mongrel2::Config::Host < Mongrel2::Config( :host )
|
|
13
13
|
# name TEXT,
|
14
14
|
# matching TEXT);
|
15
15
|
|
16
|
+
|
17
|
+
#
|
18
|
+
# :section: Associations
|
19
|
+
#
|
20
|
+
|
21
|
+
##
|
22
|
+
# The routes[rdoc-ref:Mongrel2::Config::Route] that this host has.
|
16
23
|
one_to_many :routes
|
24
|
+
|
25
|
+
##
|
26
|
+
# The server[rdoc-ref:Mongrel2::Config::Server] this host belongs to.
|
17
27
|
many_to_one :server
|
18
28
|
|
19
29
|
|
30
|
+
#
|
31
|
+
# :section: Hooks
|
32
|
+
#
|
33
|
+
|
20
34
|
### Clean up the host's routes when it's destroyed.
|
21
35
|
def before_destroy
|
22
36
|
self.routes.each( &:destroy )
|
23
37
|
end
|
24
38
|
|
25
39
|
|
40
|
+
#
|
41
|
+
# :section: DSL mixin
|
42
|
+
#
|
43
|
+
|
26
44
|
### DSL methods for the Server context besides those automatically-generated from its
|
27
45
|
### columns.
|
28
46
|
module DSLMethods
|
@@ -14,6 +14,23 @@ class Mongrel2::Config::Route < Mongrel2::Config( :route )
|
|
14
14
|
# target_id INTEGER,
|
15
15
|
# target_type TEXT);
|
16
16
|
|
17
|
+
|
18
|
+
### Return the Route that corresponds to the given +request+.
|
19
|
+
def self::for_request( request )
|
20
|
+
pattern = request.headers.pattern
|
21
|
+
return self.filter( path: pattern ).first
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
#
|
26
|
+
# :section: Associations
|
27
|
+
#
|
28
|
+
|
29
|
+
##
|
30
|
+
# The Mongrel2::Config::Host this route belongs to.
|
31
|
+
many_to_one :host
|
32
|
+
|
33
|
+
|
17
34
|
### Fetch the route's target, which is either a Mongrel2::Config::Directory,
|
18
35
|
### Mongrel2::Config::Proxy, or Mongrel2::Config::Handler object.
|
19
36
|
def target
|
@@ -25,10 +25,23 @@ class Mongrel2::Config::Server < Mongrel2::Config( :server )
|
|
25
25
|
# port INTEGER,
|
26
26
|
# use_ssl INTEGER default 0);
|
27
27
|
|
28
|
+
#
|
29
|
+
# :section: Associations
|
30
|
+
#
|
31
|
+
|
32
|
+
##
|
33
|
+
# The hosts[rdoc-ref:Mongrel2::Config::Host] that belong to this server.
|
28
34
|
one_to_many :hosts
|
35
|
+
|
36
|
+
##
|
37
|
+
# The filters[rdoc-ref:Mongrel2::Config::Filter] that will be loaded by this server.
|
29
38
|
one_to_many :filters
|
30
39
|
|
31
40
|
|
41
|
+
#
|
42
|
+
# :section: Dataset Methods
|
43
|
+
#
|
44
|
+
|
32
45
|
##
|
33
46
|
# Return the dataset for looking up a server by its UUID.
|
34
47
|
# :singleton-method: by_uuid
|
@@ -37,6 +50,16 @@ class Mongrel2::Config::Server < Mongrel2::Config( :server )
|
|
37
50
|
def_dataset_method( :by_uuid ) {|uuid| filter(:uuid => uuid).limit(1) }
|
38
51
|
|
39
52
|
|
53
|
+
#
|
54
|
+
# :section: Socket/Pathname Convenience Methods
|
55
|
+
#
|
56
|
+
|
57
|
+
### Return a Pathname for the server's chroot directory.
|
58
|
+
def chroot_path
|
59
|
+
return Pathname( self.chroot )
|
60
|
+
end
|
61
|
+
|
62
|
+
|
40
63
|
### Return the URI for its control socket.
|
41
64
|
def control_socket_uri
|
42
65
|
# Find the control socket relative to the server's chroot
|
@@ -46,7 +69,7 @@ class Mongrel2::Config::Server < Mongrel2::Config( :server )
|
|
46
69
|
scheme, sock_path = csock_uri.split( '://', 2 )
|
47
70
|
self.log.debug " chrooted socket path is: %p" % [ sock_path ]
|
48
71
|
|
49
|
-
csock_path =
|
72
|
+
csock_path = self.chroot_path + sock_path
|
50
73
|
self.log.debug " fully-qualified path is: %p" % [ csock_path ]
|
51
74
|
csock_uri = "%s://%s" % [ scheme, csock_path ]
|
52
75
|
|
@@ -63,11 +86,10 @@ class Mongrel2::Config::Server < Mongrel2::Config( :server )
|
|
63
86
|
|
64
87
|
### Return a Pathname for the server's PID file with its chroot directory prepended.
|
65
88
|
def pid_file_path
|
66
|
-
base = Pathname( self.chroot )
|
67
89
|
pidfile = self.pid_file
|
68
90
|
pidfile.slice!( 0, 1 ) if pidfile.start_with?( '/' )
|
69
91
|
|
70
|
-
return
|
92
|
+
return self.chroot_path + pidfile
|
71
93
|
end
|
72
94
|
|
73
95
|
|
data/lib/mongrel2/connection.rb
CHANGED
@@ -149,6 +149,7 @@ class Mongrel2::Connection
|
|
149
149
|
### Tell the server to close the connection associated with the given +sender_id+ and
|
150
150
|
### +conn_id+.
|
151
151
|
def send_close( sender_id, conn_id )
|
152
|
+
self.log.info "Sending kill message to connection %d" % [ conn_id ]
|
152
153
|
self.send( sender_id, conn_id, '' )
|
153
154
|
end
|
154
155
|
|
data/lib/mongrel2/handler.rb
CHANGED
@@ -202,6 +202,10 @@ class Mongrel2::Handler
|
|
202
202
|
self.handle_disconnect( request )
|
203
203
|
return nil
|
204
204
|
|
205
|
+
elsif request.upload_started?
|
206
|
+
self.log.debug "async upload start!"
|
207
|
+
return self.handle_async_upload_start( request )
|
208
|
+
|
205
209
|
else
|
206
210
|
case request
|
207
211
|
when Mongrel2::HTTPRequest
|
@@ -290,6 +294,28 @@ class Mongrel2::Handler
|
|
290
294
|
end
|
291
295
|
|
292
296
|
|
297
|
+
### Handle an asynchronous upload start notification. These are sent to notify the
|
298
|
+
### handler that a request that exceeds the server's <tt>limits.content_length</tt>
|
299
|
+
### has been received. The default implementation cancels any such uploads by
|
300
|
+
### replying with an empty string. If the request should be accepted, your handler
|
301
|
+
### should override this and do nothing if the request should continue. You'll receive
|
302
|
+
### a new request via the regular callback when the upload completes whose entity body
|
303
|
+
### is open to the spooled file.
|
304
|
+
def handle_async_upload_start( request )
|
305
|
+
explanation = "If you wish to handle requests like this, either set your server's "
|
306
|
+
explanation << "'limits.content_length' setting to a higher value than %d, or override " %
|
307
|
+
[ request.content_length ]
|
308
|
+
explanation << "#handle_async_upload_start."
|
309
|
+
|
310
|
+
self.log.warn "Async upload from %s dropped." % [ request.remote_ip ]
|
311
|
+
self.log.info( explanation )
|
312
|
+
|
313
|
+
self.conn.reply_close( request )
|
314
|
+
|
315
|
+
return nil
|
316
|
+
end
|
317
|
+
|
318
|
+
|
293
319
|
#
|
294
320
|
# :section: Signal Handling
|
295
321
|
# These methods set up some behavior for starting, restarting, and stopping
|
data/lib/mongrel2/httprequest.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
#!/usr/bin/ruby
|
2
2
|
|
3
|
-
require 'ipaddr'
|
4
3
|
require 'loggability'
|
5
4
|
|
6
5
|
require 'mongrel2/request' unless defined?( Mongrel2::Request )
|
@@ -89,13 +88,6 @@ class Mongrel2::HTTPRequest < Mongrel2::Request
|
|
89
88
|
end
|
90
89
|
|
91
90
|
|
92
|
-
### Fetch the original requestor IP address.
|
93
|
-
def remote_ip
|
94
|
-
ips = [ self.headers.x_forwarded_for ]
|
95
|
-
return IPAddr.new( ips.flatten.first )
|
96
|
-
end
|
97
|
-
|
98
|
-
|
99
91
|
#########
|
100
92
|
protected
|
101
93
|
#########
|
@@ -107,7 +99,7 @@ class Mongrel2::HTTPRequest < Mongrel2::Request
|
|
107
99
|
self.headers[:method],
|
108
100
|
self.headers.uri,
|
109
101
|
self.headers.version,
|
110
|
-
(self.body.
|
102
|
+
(self.body.size / 1024.0),
|
111
103
|
]
|
112
104
|
end
|
113
105
|
|
data/lib/mongrel2/request.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
#!/usr/bin/ruby
|
2
2
|
|
3
|
+
require 'ipaddr'
|
3
4
|
require 'stringio'
|
4
5
|
require 'tnetstring'
|
5
6
|
require 'yajl'
|
@@ -171,6 +172,13 @@ class Mongrel2::Request
|
|
171
172
|
end
|
172
173
|
|
173
174
|
|
175
|
+
### Fetch the original requestor IP address.
|
176
|
+
def remote_ip
|
177
|
+
ips = [ self.headers.x_forwarded_for ]
|
178
|
+
return IPAddr.new( ips.flatten.first )
|
179
|
+
end
|
180
|
+
|
181
|
+
|
174
182
|
#
|
175
183
|
# :section: Async Upload Support
|
176
184
|
# See http://mongrel2.org/static/book-finalch6.html#x8-810005.5 for details.
|
@@ -181,12 +189,12 @@ class Mongrel2::Request
|
|
181
189
|
raise Mongrel2::UploadError, "invalid upload: upload headers don't match" unless
|
182
190
|
self.upload_headers_match?
|
183
191
|
|
184
|
-
|
185
|
-
raise Mongrel2::UploadError, "couldn't find the
|
186
|
-
|
192
|
+
route = Mongrel2::Config::Route.for_request( self ) or
|
193
|
+
raise Mongrel2::UploadError, "couldn't find the route config for %s" % [ self ]
|
194
|
+
server = route.host.server
|
187
195
|
|
188
196
|
relpath = Pathname( self.headers.x_mongrel2_upload_done )
|
189
|
-
chrooted =
|
197
|
+
chrooted = server.chroot_path + relpath
|
190
198
|
|
191
199
|
if chrooted.exist?
|
192
200
|
return chrooted
|
data/spec/lib/helpers.rb
CHANGED
@@ -254,6 +254,18 @@ describe Mongrel2::Handler do
|
|
254
254
|
response.should be_nil()
|
255
255
|
end
|
256
256
|
|
257
|
+
it "cancels async upload notices by default" do
|
258
|
+
req = make_request( 'METHOD' => 'POST', :headers => {'x-mongrel2-upload-start' => 'uploadfile.XXX'} )
|
259
|
+
@request_sock.should_receive( :recv ).and_return( req )
|
260
|
+
@response_sock.should_receive( :send ).with( "#{TEST_UUID} 1:8, " )
|
261
|
+
|
262
|
+
res = OneShotHandler.new( TEST_UUID, TEST_SEND_SPEC, TEST_RECV_SPEC ).run
|
263
|
+
|
264
|
+
res.transactions.should have( 1 ).member
|
265
|
+
request, response = res.transactions.first
|
266
|
+
response.should be_nil()
|
267
|
+
end
|
268
|
+
|
257
269
|
it "re-establishes its connection when told to restart" do
|
258
270
|
res = OneShotHandler.new( TEST_UUID, TEST_SEND_SPEC, TEST_RECV_SPEC )
|
259
271
|
original_conn = res.conn
|
@@ -123,20 +123,6 @@ describe Mongrel2::HTTPRequest do
|
|
123
123
|
}.to raise_error( ArgumentError, /invalid value for integer/i )
|
124
124
|
end
|
125
125
|
|
126
|
-
it "provides a convenience method for fetching the requestor's IP address" do
|
127
|
-
@req.headers.merge!(
|
128
|
-
'X-Forwarded-For' => '127.0.0.1'
|
129
|
-
)
|
130
|
-
@req.remote_ip.to_s.should == '127.0.0.1'
|
131
|
-
end
|
132
|
-
|
133
|
-
it "fetching the requestor's IP address even when travelling via proxies" do
|
134
|
-
@req.headers.merge!(
|
135
|
-
'X-Forwarded-For' => [ '127.0.0.1', '8.8.8.8', '4.4.4.4' ]
|
136
|
-
)
|
137
|
-
@req.remote_ip.to_s.should == '127.0.0.1'
|
138
|
-
end
|
139
|
-
|
140
126
|
end
|
141
127
|
|
142
128
|
end
|
@@ -120,6 +120,20 @@ describe Mongrel2::Request do
|
|
120
120
|
@req.body.should be( testobj )
|
121
121
|
end
|
122
122
|
|
123
|
+
it "provides a convenience method for fetching the requestor's IP address" do
|
124
|
+
@req.headers.merge!(
|
125
|
+
'X-Forwarded-For' => '127.0.0.1'
|
126
|
+
)
|
127
|
+
@req.remote_ip.to_s.should == '127.0.0.1'
|
128
|
+
end
|
129
|
+
|
130
|
+
it "fetching the requestor's IP address even when travelling via proxies" do
|
131
|
+
@req.headers.merge!(
|
132
|
+
'X-Forwarded-For' => [ '127.0.0.1', '8.8.8.8', '4.4.4.4' ]
|
133
|
+
)
|
134
|
+
@req.remote_ip.to_s.should == '127.0.0.1'
|
135
|
+
end
|
136
|
+
|
123
137
|
end
|
124
138
|
|
125
139
|
|
@@ -204,15 +218,20 @@ describe Mongrel2::Request do
|
|
204
218
|
|
205
219
|
before( :all ) do
|
206
220
|
setup_config_db()
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
221
|
+
|
222
|
+
# Set up a test server config so the request can find the server's chroot
|
223
|
+
server 'specs' do
|
224
|
+
default_host 'localhost'
|
225
|
+
access_log 'access.log'
|
226
|
+
error_log 'error.log'
|
227
|
+
chroot Dir.tmpdir
|
228
|
+
pid_file '/var/run/mongrel2.pid'
|
229
|
+
port 8113
|
230
|
+
|
231
|
+
host 'localhost' do
|
232
|
+
route '/form', handler( TEST_SEND_SPEC, 'upload-handler', TEST_RECV_SPEC )
|
233
|
+
end
|
234
|
+
end
|
216
235
|
end
|
217
236
|
|
218
237
|
before( :each ) do
|
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.26.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -36,7 +36,7 @@ cert_chain:
|
|
36
36
|
YUhDS0xaZFNLai9SSHVUT3QrZ2JsUmV4OEZBaDhOZUEKY21saFhlNDZwWk5K
|
37
37
|
Z1dLYnhaYWg4NWpJang5NWhSOHZPSStOQU01aUg5a09xSzEzRHJ4YWNUS1Bo
|
38
38
|
cWo1UGp3RgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
|
39
|
-
date: 2012-06-
|
39
|
+
date: 2012-06-26 00:00:00.000000000 Z
|
40
40
|
dependencies:
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: nokogiri
|
metadata.gz.sig
CHANGED
Binary file
|