mongrel2 0.23.0 → 0.24.0

Sign up to get free protection for your applications and to get access to all the features.
data.tar.gz.sig CHANGED
Binary file
data/ChangeLog CHANGED
@@ -1,8 +1,66 @@
1
+ 2012-05-20 Michael Granger <ged@FaerieMUD.org>
2
+
3
+ * .rvm.gems:
4
+ Comment out amalgalite rvmrc gem until
5
+ https://github.com/copiousfreetime/amalgalite/pull/22 is fixed
6
+ [b872e092ed92] [tip]
7
+
8
+ 2012-05-21 Michael Granger <ged@FaerieMUD.org>
9
+
10
+ * Manifest.txt, examples/.env, examples/async-upload.rb,
11
+ examples/config.rb, lib/mongrel2/config.rb,
12
+ lib/mongrel2/httprequest.rb, spec/mongrel2/config_spec.rb:
13
+ Change Config.settings to a Table, small fixups for async upload.
14
+ [e2384875455d]
15
+
16
+ * .tm_properties, data/mongrel2/bootstrap.html, examples/.env,
17
+ examples/Procfile, examples/async-upload.rb, examples/config.rb,
18
+ examples/run, lib/mongrel2/exceptions.rb,
19
+ lib/mongrel2/httprequest.rb, spec/mongrel2/httprequest_spec.rb:
20
+ Add support for async uploads
21
+ [0b20bfda9eea]
22
+
23
+ 2012-05-18 Michael Granger <ged@FaerieMUD.org>
24
+
25
+ * .rvm.gems:
26
+ Bumping Loggability dependency for inheritance bugfix
27
+ [0c8cef0e6065]
28
+
29
+ 2012-05-17 Michael Granger <ged@FaerieMUD.org>
30
+
31
+ * .hgtags:
32
+ Added tag v0.23.0 for changeset 644f1ddbfbd1
33
+ [82d6cd587b0a]
34
+
35
+ * .hgsigs:
36
+ Added signature for changeset 7d768d6e98ab
37
+ [644f1ddbfbd1] [v0.23.0]
38
+
39
+ * History.rdoc, lib/mongrel2.rb:
40
+ Bump the minor version, update history.
41
+ [7d768d6e98ab]
42
+
43
+ * lib/mongrel2/connection.rb, lib/mongrel2/handler.rb,
44
+ spec/mongrel2/handler_spec.rb:
45
+ Add a convenience method to Mongrel2::Handler for fetching its
46
+ associated config object.
47
+ [30af037aa0be]
48
+
49
+ * bin/m2sh.rb:
50
+ Fix typos in m2sh.rb's exception handler
51
+ [b7c5ca68fe74]
52
+
53
+ 2012-05-10 Michael Granger <ged@FaerieMUD.org>
54
+
55
+ * .rvm.gems, Rakefile:
56
+ Bumping dependency on Loggability to 0.2.
57
+ [b98ed24dfb83]
58
+
1
59
  2012-05-07 Michael Granger <ged@FaerieMUD.org>
2
60
 
3
61
  * .hgtags:
4
62
  Added tag v0.22.1 for changeset ab969af3bf2c
5
- [142eade04d61] [tip]
63
+ [142eade04d61]
6
64
 
7
65
  * .hgsigs:
8
66
  Added signature for changeset c68ca662121f
@@ -40,7 +98,7 @@
40
98
  spec/mongrel2/logging_spec.rb, spec/mongrel2/mixins_spec.rb,
41
99
  spec/mongrel2_spec.rb:
42
100
  Convert to Loggability for logging.
43
- [0da53476f796] [github/master]
101
+ [0da53476f796]
44
102
 
45
103
  2012-04-25 Michael Granger <ged@FaerieMUD.org>
46
104
 
@@ -261,7 +319,7 @@
261
319
  .database_initialized?, so add a new .without_sql_logging method for
262
320
  temporarily disabling SQL logging, and wrap that around the methods
263
321
  in quesion.
264
- [6b62343b4e5a] [github/master@default]
322
+ [6b62343b4e5a]
265
323
 
266
324
  * .rvm.gems, Rakefile:
267
325
  Add simplecov to dev dependencies
data/History.rdoc CHANGED
@@ -1,3 +1,10 @@
1
+ == v0.24.0 [2012-05-31] Michael Granger <ged@FaerieMUD.org>
2
+
3
+ - Fix a bug when duping a Mongrel2::Table with immediate objects as values.
4
+ - Change Config.settings to a Table.
5
+ - Add support for Mongrel2 async uploads.
6
+
7
+
1
8
  == v0.23.0 [2012-05-17] Michael Granger <ged@FaerieMUD.org>
2
9
 
3
10
  - Add a convenience method to Mongrel2::Handler for fetching its
data/Manifest.txt CHANGED
@@ -13,7 +13,10 @@ data/mongrel2/css/master.css
13
13
  data/mongrel2/js/websock-test.js
14
14
  data/mongrel2/mimetypes.sql
15
15
  data/mongrel2/websock-test.html
16
+ examples/.env
17
+ examples/Procfile
16
18
  examples/README.txt
19
+ examples/async-upload.rb
17
20
  examples/config.rb
18
21
  examples/helloworld-handler.rb
19
22
  examples/request-dumper.rb
@@ -16,6 +16,8 @@
16
16
  <section>
17
17
  <ol>
18
18
  <li><a href="/hello">Hello World</a> (<a href="/source/helloworld-handler.rb">source</a>) </li>
19
+ <li><a href="/async-upload">Async Upload Demo</a>
20
+ (<a href="/source/async-upload.rb">source</a>) </li>
19
21
  <li><a href="/dump">Dump Request</a> (<a href="/source/request-dumper.rb">source</a>) </li>
20
22
  <li><a href="/websock-test.html">Web Socket Test</a></li>
21
23
  </ol>
@@ -23,7 +25,7 @@
23
25
 
24
26
  <footer>
25
27
  <p>Copyright © 2011-2012 Michael Granger &lt;<a href="mailto:ged@FaerieMUD.org">ged@FaerieMUD.org</a>&gt;.</p>
26
- <p><tt>$Id: bootstrap.html,v fea3cd02d23c 2012/03/07 16:07:50 ged $</tt></p>
28
+ <p><tt>$Id: bootstrap.html,v 0b20bfda9eea 2012/05/22 00:34:22 ged $</tt></p>
27
29
  </footer>
28
30
  </body>
29
31
  </html>
data/examples/.env ADDED
@@ -0,0 +1 @@
1
+ RUBYOPT=-I../lib
data/examples/Procfile ADDED
@@ -0,0 +1,6 @@
1
+ # Foreman Procfile
2
+ mongrel2: ruby ../bin/m2sh.rb -c examples.sqlite start
3
+ helloworld: ruby helloworld-handler.rb
4
+ async_upload: ruby async-upload.rb
5
+ request_dumper: ruby request-dumper.rb
6
+
@@ -0,0 +1,110 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'erb'
4
+ require 'loggability'
5
+ require 'mongrel2/config'
6
+ require 'mongrel2/handler'
7
+
8
+ # A example of how to allow Mongrel2's async uploads.
9
+ class AsyncUploadHandler < Mongrel2::Handler
10
+
11
+ ### Load up the ERB template from the DATA section on instantiation.
12
+ def initialize( * )
13
+ super
14
+ @template = self.load_template
15
+ end
16
+
17
+
18
+ ### Load the ERB template from this file's DATA section.
19
+ def load_template
20
+ raw = IO.read( __FILE__ ).split( /^__END__$/m, 2 ).last
21
+ return ERB.new( raw, nil, '<%>' )
22
+ end
23
+
24
+
25
+ ### Mongrel2 async upload callback -- allow uploads to proceed.
26
+ def handle_upload_start( request )
27
+ self.log.info "Upload started: %s" % [ request.header.x_mongrel2_upload_start ]
28
+ return nil # Do nothing
29
+ end
30
+
31
+
32
+ ### Mongrel2 async upload callback -- finish the upload.
33
+ def handle_upload_done( request )
34
+ self.log.warn "Upload finished: %s (%0.2fK, %s)" %
35
+ [ request.uploaded_file, request.content_length, request.content_type ]
36
+
37
+ response = request.response
38
+ response.puts "Upload complete: %s" % [ request.uploaded_file ]
39
+ response.content_type = 'text/plain'
40
+
41
+ return response
42
+ rescue Mongrel2::UploadError => err
43
+ self.log.error "%s when finishing an upload: %s" % [ err.class, err.message ]
44
+ self.log.debug { err.backtrace.join("\n\t") }
45
+
46
+ finish_with HTTP::BAD_REQUEST, 'malformed upload headers'
47
+ end
48
+
49
+
50
+ ### Regular request -- show the upload form.
51
+ def handle( request )
52
+ # If it's the 'upload started' notification, use that handler method
53
+ if request.upload_started?
54
+ return self.handle_upload_start( request )
55
+
56
+ # If it's a finished upload, use that handler method
57
+ elsif request.upload_done?
58
+ return self.handle_upload_done( request )
59
+
60
+ else
61
+ response = request.response
62
+
63
+ settings = Mongrel2::Config.settings
64
+
65
+ response.headers.content_type = 'text/html'
66
+ response.puts( @template.result(binding()) )
67
+
68
+ return response
69
+ end
70
+ end
71
+
72
+ end # class HelloWorldHandler
73
+
74
+ configdb = ARGV.shift || 'examples.sqlite'
75
+
76
+ # Log to a file instead of STDERR for a bit more speed.
77
+ # Loggability.output_to( 'hello-world.log' )
78
+ Loggability.level = :debug
79
+
80
+ # Point to the config database, which will cause the handler to use
81
+ # its ID to look up its own socket info.
82
+ Mongrel2::Config.configure( configdb: configdb )
83
+ AsyncUploadHandler.run( 'async-upload' )
84
+
85
+ __END__
86
+ <!DOCTYPE html>
87
+ <html lang="en">
88
+ <head>
89
+ <title>Ruby-Mongrel2 Async Upload Demo</title>
90
+ <meta charset="utf-8">
91
+ </head>
92
+
93
+ <body>
94
+
95
+ <h1>Ruby-Mongrel2 Async Upload Demo</h1>
96
+
97
+ <form action="<%= request.headers.uri %>" method="post" accept-charset="utf-8"
98
+ enctype="multipart/form-data">
99
+
100
+ <label for="file">Choose a file</label>
101
+ <input type="file" name="uploaded-file" value="">
102
+
103
+ <p>Upload will be async if it's larger than:
104
+ <%= settings['limits.content_length'] %> bytes.</p>
105
+
106
+ <p><input type="submit" value="Upload &rarr;"></p>
107
+ </form>
108
+
109
+ </body>
110
+ </html>
data/examples/config.rb CHANGED
@@ -1,10 +1,17 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
+ require 'pathname'
4
+ require 'tmpdir'
5
+
3
6
  # The Mongrel config used by the examples. Load it with:
4
7
  #
5
8
  # m2sh.rb -c examples.sqlite load examples/config.rb
6
9
  #
7
10
 
11
+ examples_dir = Pathname( __FILE__ ).dirname
12
+ basedir = examples_dir.parent
13
+ upload_dir = Pathname( Dir.tmpdir )
14
+
8
15
  # samples server
9
16
  server 'examples' do
10
17
 
@@ -14,7 +21,7 @@ server 'examples' do
14
21
  access_log '/logs/access.log'
15
22
  error_log '/logs/error.log'
16
23
  chroot '/var/mongrel2'
17
- pid_file '/run/mongrel2.pid'
24
+ pid_file '/var/run/mongrel2.pid'
18
25
 
19
26
  bind_addr '127.0.0.1'
20
27
  port 8113
@@ -22,12 +29,13 @@ server 'examples' do
22
29
  # your main host
23
30
  host 'localhost' do
24
31
 
25
- route '/', directory( 'data/mongrel2/', 'bootstrap.html', 'text/html' )
26
- route '/source', directory( 'examples/', 'README.txt', 'text/plain' )
32
+ route '/', directory( "#{basedir}/data/mongrel2/", 'bootstrap.html', 'text/html' )
33
+ route '/source', directory( "#{basedir}/examples/", 'README.txt', 'text/plain' )
27
34
 
28
35
  # Handlers
29
36
  dumper = handler( 'tcp://127.0.0.1:9997', 'request-dumper', protocol: 'tnetstring' )
30
37
  route '/hello', handler( 'tcp://127.0.0.1:9999', 'helloworld-handler' )
38
+ route '/async-upload', handler( 'tcp://127.0.0.1:9950', 'async-upload' )
31
39
  route '/dump', dumper
32
40
  route '/ws', handler( 'tcp://127.0.0.1:9995', 'ws-echo' )
33
41
  route '@js', dumper
@@ -38,4 +46,11 @@ server 'examples' do
38
46
  end
39
47
 
40
48
  setting "zeromq.threads", 1
49
+ setting "limits.content_length", 4096
50
+ setting "upload.temp_store", upload_dir + 'mongrel2.upload.XXXXXX'
51
+
52
+ mkdir_p 'var/run'
53
+ mkdir_p 'logs'
54
+ mkdir_p '/tmp/mongrel2-uploads'
41
55
 
56
+ puts "Upload dir is: #{upload_dir}"
data/examples/run CHANGED
@@ -1,17 +1,22 @@
1
1
  #!/bin/sh
2
2
 
3
- examplesdir=$(dirname $0)
4
-
5
- echo "Creating the config database..."
6
- ruby -rubygems -Ilib $examplesdir/config.rb
3
+ if [ "$(type foreman 2>/dev/null)" == "" ]; then
4
+ echo "You need Foreman installed to start the examples (gem install foreman)"
5
+ exit 1
6
+ fi
7
7
 
8
- echo "Starting Mongrel2..."
9
- m2sh start -db examples.sqlite -host localhost &
8
+ examplesdir=$(dirname $0)
10
9
 
11
- echo "Starting the 'helloworld' handler..."
12
- ruby -rubygems -Ilib $examplesdir/helloworld-handler.rb &
10
+ echo "Creating/updating the config database..."
11
+ ruby -rubygems -I${examplesdir}/../lib $examplesdir/../bin/m2sh.rb \
12
+ -c examples.sqlite load $examplesdir/config.rb
13
13
 
14
- echo "Starting the request dumper..."
15
- ruby -rubygems -Ilib $examplesdir/request-dumper.rb &
14
+ if [ $? != 0 ]; then
15
+ echo "Oops, problems installing the config DB. Aborting."
16
+ exit 1
17
+ fi
16
18
 
17
19
  echo "Okay, now point a browser to http://localhost:8113/."
20
+ cd $examplesdir
21
+ foreman start
22
+
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.0'
23
+ VERSION = '0.24.0'
24
24
 
25
25
  # Version-control revision constant
26
- REVISION = %q$Revision: 7d768d6e98ab $
26
+ REVISION = %q$Revision: 3ed1175a2f9e $
27
27
 
28
28
 
29
29
  require 'mongrel2/constants'
@@ -27,6 +27,7 @@ end
27
27
 
28
28
 
29
29
  require 'mongrel2' unless defined?( Mongrel2 )
30
+ require 'mongrel2/table'
30
31
 
31
32
  module Mongrel2
32
33
 
@@ -154,11 +155,7 @@ module Mongrel2
154
155
  ### Symbols.
155
156
  def self::settings
156
157
  setting_hash = Mongrel2::Config::Setting.to_hash( :key, :value )
157
- setting_hash.keys.each do |k|
158
- setting_hash[ k.to_sym ] = setting_hash.delete( k )
159
- end
160
-
161
- return setting_hash
158
+ return Mongrel2::Table.new( setting_hash )
162
159
  end
163
160
 
164
161
 
@@ -53,6 +53,10 @@ module Mongrel2
53
53
 
54
54
  end # class ControlError
55
55
 
56
+ # An exception type raised by Mongrel2::HTTPRequest if an async upload request is
57
+ # received, but has different Mongrel2 upload headers.
58
+ class UploadError < Mongrel2::Exception; end
59
+
56
60
  end # module Mongrel2
57
61
 
58
62
 
@@ -60,6 +60,15 @@ class Mongrel2::HTTPRequest < Mongrel2::Request
60
60
  end
61
61
 
62
62
 
63
+ ### Returns the size of the request's entity body, as specified by its
64
+ ### 'Content-Length' header. Note that this may or may not correspond to
65
+ ### the actual byte size of the body.
66
+ def content_length
67
+ return 0 unless self.header.member?( :content_length )
68
+ return Integer( self.header.content_length )
69
+ end
70
+
71
+
63
72
  ### Fetch the mimetype of the request's content, as set in its header.
64
73
  def content_type
65
74
  return self.headers.content_type
@@ -91,6 +100,48 @@ class Mongrel2::HTTPRequest < Mongrel2::Request
91
100
  end
92
101
 
93
102
 
103
+ #
104
+ # :section: Async Upload Support
105
+ # See http://mongrel2.org/static/book-finalch6.html#x8-810005.5 for details.
106
+ #
107
+
108
+ ### The Pathname, relative to Mongrel2's chroot path, of the uploaded entity body.
109
+ def uploaded_file
110
+ raise Mongrel2::UploadError, "invalid upload: upload headers don't match" unless
111
+ self.upload_headers_match?
112
+ return Pathname( self.headers.x_mongrel2_upload_done )
113
+ end
114
+
115
+
116
+ ### Returns +true+ if this request is an 'asynchronous upload started' notification.
117
+ def upload_started?
118
+ return self.headers.member?( :x_mongrel2_upload_start ) &&
119
+ !self.headers.member?( :x_mongrel2_upload_done )
120
+ end
121
+
122
+
123
+ ### Returns +true+ if this request is an 'asynchronous upload done' notification.
124
+ def upload_done?
125
+ return self.headers.member?( :x_mongrel2_upload_start ) &&
126
+ self.headers.member?( :x_mongrel2_upload_done )
127
+ end
128
+
129
+
130
+ ### Returns +true+ if this request is an 'asynchronous upload done' notification
131
+ ### and the two headers match (trivial guard against forgery)
132
+ def upload_headers_match?
133
+ return self.upload_done? &&
134
+ self.headers.x_mongrel2_upload_start == self.headers.x_mongrel2_upload_done
135
+ end
136
+
137
+
138
+ ### Returns true if this request is an asynchronous upload, and the filename of the
139
+ ### finished request matches the one from the starting notification.
140
+ def valid_upload?
141
+ return self.upload_done? && self.upload_headers_match?
142
+ end
143
+
144
+
94
145
  #########
95
146
  protected
96
147
  #########
@@ -57,28 +57,8 @@ class Mongrel2::Table
57
57
 
58
58
 
59
59
  ### Make sure the inner Hash is unique on duplications.
60
- def initialize_dup( * ) # :nodoc:
61
- @hash = @hash.dup
62
- @hash.each do |k, v|
63
- if v.is_a?( Array )
64
- @hash[ k ] = v.map( &:dup )
65
- else
66
- @hash[ k ] = v.dup
67
- end
68
- end
69
- end
70
-
71
-
72
- ### Make sure the inner Hash is unique on clones.
73
- def initialize_clone( * ) # :nodoc:
74
- @hash = @hash.clone
75
- @hash.each do |k, v|
76
- if v.is_a?( Array )
77
- @hash[ k ] = v.map( &:clone )
78
- else
79
- @hash[ k ] = v.clone
80
- end
81
- end
60
+ def initialize_copy( * ) # :nodoc:
61
+ @hash = deep_copy( @hash )
82
62
  end
83
63
 
84
64
 
@@ -237,6 +217,30 @@ class Mongrel2::Table
237
217
  end
238
218
 
239
219
 
220
+ ### Recursively copying the specified +obj+ and return the result.
221
+ def deep_copy( obj )
222
+ # Handle mocks during testing
223
+ return obj if obj.class.name == 'RSpec::Mocks::Mock'
224
+
225
+ return case obj
226
+ when NilClass, Numeric, TrueClass, FalseClass, Symbol
227
+ obj
228
+
229
+ when Array
230
+ obj.map {|o| deep_copy(o) }
231
+
232
+ when Hash
233
+ newhash = {}
234
+ obj.each do |k,v|
235
+ newhash[ deep_copy(k) ] = deep_copy( v )
236
+ end
237
+ newhash
238
+
239
+ else
240
+ obj.clone
241
+ end
242
+ end
243
+
240
244
  end # class Mongrel2::Table
241
245
 
242
246
  # vim: set nosta noet ts=4 sw=4:
@@ -73,7 +73,7 @@ describe Mongrel2::Config do
73
73
  Mongrel2::Config.init_database
74
74
  Mongrel2::Config::Setting.dataset.truncate
75
75
  Mongrel2::Config::Setting.create( key: 'control_port', value: 'ipc://var/run/control.sock' )
76
- Mongrel2::Config.settings.should be_a( Hash )
76
+ Mongrel2::Config.settings.should respond_to( :[] )
77
77
  Mongrel2::Config.settings.should have( 1 ).member
78
78
  Mongrel2::Config.settings[ :control_port ].should == 'ipc://var/run/control.sock'
79
79
  end
@@ -89,6 +89,7 @@ describe Mongrel2::HTTPRequest do
89
89
 
90
90
  before( :each ) do
91
91
  @req.headers.merge!(
92
+ 'Content-length' => '28113',
92
93
  'Content-type' => 'application/x-pdf',
93
94
  'Content-encoding' => 'gzip'
94
95
  )
@@ -112,6 +113,22 @@ describe Mongrel2::HTTPRequest do
112
113
  @req.content_encoding.should == 'identity'
113
114
  end
114
115
 
116
+ it "provides a convenience method for fetching the request's Content-length header" do
117
+ @req.content_length.should == 28113
118
+ end
119
+
120
+ it "returns 0 as the content_length if the request doesn't have a Content-length header" do
121
+ @req.headers.delete( :content_length )
122
+ @req.content_length.should == 0
123
+ end
124
+
125
+ it "raises an exception if the Content-length header contains something other than an integer" do
126
+ @req.headers.content_length = 'Lots'
127
+ expect {
128
+ @req.content_length
129
+ }.to raise_error( ArgumentError, /invalid value for integer/i )
130
+ end
131
+
115
132
  it "provides a convenience method for fetching the requestor's IP address" do
116
133
  @req.headers.merge!(
117
134
  'X-Forwarded-For' => '127.0.0.1'
@@ -126,6 +143,46 @@ describe Mongrel2::HTTPRequest do
126
143
  @req.remote_ip.to_s.should == '127.0.0.1'
127
144
  end
128
145
 
146
+ it "knows if it's an 'async upload started' notification" do
147
+ @req.headers.x_mongrel2_upload_start = '/tmp/mongrel2.upload.20120503-54578-rs3l2g'
148
+ @req.should be_upload_started()
149
+ @req.should_not be_upload_done()
150
+ end
151
+
152
+ it "knows if it's an 'async upload done' notification" do
153
+ @req.headers.x_mongrel2_upload_start = '/tmp/mongrel2.upload.20120503-54578-rs3l2g'
154
+ @req.headers.x_mongrel2_upload_done = '/tmp/mongrel2.upload.20120503-54578-rs3l2g'
155
+ @req.should_not be_upload_started()
156
+ @req.should be_upload_done()
157
+ @req.should be_valid_upload()
158
+ end
159
+
160
+ it "knows if it's not a valid 'async upload done' notification" do
161
+ @req.headers.x_mongrel2_upload_start = '/tmp/mongrel2.upload.20120503-54578-rs3l2g'
162
+ @req.headers.x_mongrel2_upload_done = '/etc/passwd'
163
+ @req.should_not be_upload_started()
164
+ @req.should be_upload_done()
165
+ @req.should_not be_valid_upload()
166
+ end
167
+
168
+ it "raises an exception if the uploaded file fetched with mismatched headers" do
169
+ @req.headers.x_mongrel2_upload_start = '/tmp/mongrel2.upload.20120503-54578-rs3l2g'
170
+ @req.headers.x_mongrel2_upload_done = '/etc/passwd'
171
+
172
+ expect {
173
+ @req.uploaded_file
174
+ }.to raise_error( Mongrel2::UploadError, /upload headers/i )
175
+ end
176
+
177
+ it "can return a Pathname object for the uploaded file if it's valid" do
178
+ @req.headers.x_mongrel2_upload_start = '/tmp/mongrel2.upload.20120503-54578-rs3l2g'
179
+ @req.headers.x_mongrel2_upload_done = '/tmp/mongrel2.upload.20120503-54578-rs3l2g'
180
+
181
+ @req.should be_valid_upload()
182
+ @req.uploaded_file.should be_a( Pathname )
183
+ @req.uploaded_file.to_s.should == '/tmp/mongrel2.upload.20120503-54578-rs3l2g'
184
+ end
185
+
129
186
  end
130
187
 
131
188
  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.23.0
4
+ version: 0.24.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-05-17 00:00:00.000000000 Z
39
+ date: 2012-05-31 00:00:00.000000000 Z
40
40
  dependencies:
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: nokogiri
@@ -333,7 +333,10 @@ files:
333
333
  - data/mongrel2/js/websock-test.js
334
334
  - data/mongrel2/mimetypes.sql
335
335
  - data/mongrel2/websock-test.html
336
+ - examples/.env
337
+ - examples/Procfile
336
338
  - examples/README.txt
339
+ - examples/async-upload.rb
337
340
  - examples/config.rb
338
341
  - examples/helloworld-handler.rb
339
342
  - examples/request-dumper.rb
metadata.gz.sig CHANGED
Binary file