mongrel 1.1.5-x86-mingw32 → 1.2.0.pre2-x86-mingw32

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.
Files changed (46) hide show
  1. data/History.txt +68 -0
  2. data/{Manifest → Manifest.txt} +15 -15
  3. data/{README → README.txt} +6 -0
  4. data/Rakefile +8 -0
  5. data/bin/mongrel_rails +5 -4
  6. data/examples/camping/blog.rb +0 -0
  7. data/ext/{http11_java → http11}/Http11Service.java +0 -0
  8. data/ext/http11/ext_help.h +1 -0
  9. data/ext/http11/http11.c +152 -20
  10. data/ext/http11/http11_parser.c +262 -240
  11. data/ext/http11/http11_parser.java.rl +3 -14
  12. data/ext/http11/http11_parser.rl +19 -18
  13. data/ext/http11/http11_parser_common.rl +1 -1
  14. data/ext/{http11_java → http11}/org/jruby/mongrel/Http11.java +37 -62
  15. data/ext/http11/org/jruby/mongrel/Http11Parser.java +486 -0
  16. data/lib/1.8/http11.so +0 -0
  17. data/lib/1.9/http11.so +0 -0
  18. data/lib/mongrel.rb +16 -5
  19. data/lib/mongrel/cgi.rb +2 -2
  20. data/lib/mongrel/command.rb +1 -3
  21. data/lib/mongrel/configurator.rb +5 -5
  22. data/lib/mongrel/const.rb +1 -1
  23. data/lib/mongrel/handlers.rb +5 -5
  24. data/lib/mongrel/http_request.rb +1 -1
  25. data/lib/mongrel/http_response.rb +4 -1
  26. data/lib/mongrel/rails.rb +1 -1
  27. data/tasks/gem.rake +28 -0
  28. data/tasks/native.rake +24 -0
  29. data/tasks/ragel.rake +20 -0
  30. data/test/test_conditional.rb +2 -2
  31. data/test/test_configurator.rb +4 -5
  32. data/test/test_handlers.rb +33 -24
  33. data/test/test_redirect_handler.rb +2 -3
  34. data/test/test_request_progress.rb +4 -5
  35. data/test/test_ws.rb +2 -0
  36. data/test/testhelp.rb +1 -9
  37. metadata +86 -86
  38. data.tar.gz.sig +0 -4
  39. data/CHANGELOG +0 -18
  40. data/examples/mongrel_simple_ctrl.rb +0 -92
  41. data/examples/mongrel_simple_service.rb +0 -116
  42. data/ext/http11_java/org/jruby/mongrel/Http11Parser.java +0 -572
  43. data/lib/http11.so +0 -0
  44. data/mongrel-public_cert.pem +0 -20
  45. data/mongrel.gemspec +0 -242
  46. metadata.gz.sig +0 -1
Binary file
Binary file
@@ -9,7 +9,13 @@ require 'uri'
9
9
  require 'stringio'
10
10
 
11
11
  # Compiled Mongrel extension
12
- require 'http11'
12
+ # support multiple ruby version (fat binaries under windows)
13
+ begin
14
+ require 'http11'
15
+ rescue LoadError
16
+ RUBY_VERSION =~ /(\d+.\d+)/
17
+ require "#{$1}/http11"
18
+ end
13
19
 
14
20
  # Gem conditional loader
15
21
  require 'mongrel/gems'
@@ -200,7 +206,7 @@ module Mongrel
200
206
  STDERR.puts "#{Time.now}: Client error: #{e.inspect}"
201
207
  STDERR.puts e.backtrace.join("\n")
202
208
  end
203
- request.body.delete if request and request.body.class == Tempfile
209
+ request.body.close! if request and request.body.class == Tempfile
204
210
  end
205
211
  end
206
212
 
@@ -320,10 +326,15 @@ module Mongrel
320
326
  def register(uri, handler, in_front=false)
321
327
  begin
322
328
  @classifier.register(uri, [handler])
323
- rescue URIClassifier::RegistrationError
329
+ rescue URIClassifier::RegistrationError => e
324
330
  handlers = @classifier.resolve(uri)[2]
325
- method_name = in_front ? 'unshift' : 'push'
326
- handlers.send(method_name, handler)
331
+ if handlers
332
+ # Already registered
333
+ method_name = in_front ? 'unshift' : 'push'
334
+ handlers.send(method_name, handler)
335
+ else
336
+ raise
337
+ end
327
338
  end
328
339
  handler.listener = self
329
340
  end
@@ -26,7 +26,7 @@ module Mongrel
26
26
  # Refer to DirHandler#can_serve for more information on this.
27
27
  class CGIWrapper < ::CGI
28
28
  public :env_table
29
- attr_reader :options
29
+ attr_reader :head
30
30
  attr_accessor :handler
31
31
  # Set this to false if you want calls to CGIWrapper.out to not actually send
32
32
  # the response until you force it.
@@ -105,7 +105,7 @@ module Mongrel
105
105
  when Hash
106
106
  cookie.each_value {|c| to['Set-Cookie'] = c.to_s}
107
107
  else
108
- to['Set-Cookie'] = options['cookie'].to_s
108
+ to['Set-Cookie'] = head['cookie'].to_s
109
109
  end
110
110
 
111
111
  @head.delete('cookie')
@@ -61,9 +61,7 @@ module Mongrel
61
61
  # I need to add my own -v definition to prevent the -v from exiting by default as well.
62
62
  @opt.on_tail("--version", "Show version") do
63
63
  @done_validating = true
64
- if VERSION
65
- puts "Version #{Mongrel::Const::MONGREL_VERSION}"
66
- end
64
+ puts "Version #{Mongrel::Const::MONGREL_VERSION}"
67
65
  end
68
66
 
69
67
  @opt.parse! argv
@@ -81,13 +81,13 @@ module Mongrel
81
81
 
82
82
  # Writes the PID file if we're not on Windows.
83
83
  def write_pid_file
84
- if RUBY_PLATFORM !~ /mswin|mingw/
84
+ if RUBY_PLATFORM !~ /mingw|mswin/
85
85
  log "Writing PID file to #{@pid_file}"
86
86
  open(@pid_file,"w") {|f| f.write(Process.pid) }
87
87
  open(@pid_file,"w") do |f|
88
88
  f.write(Process.pid)
89
89
  File.chmod(0644, @pid_file)
90
- end
90
+ end
91
91
  end
92
92
  end
93
93
 
@@ -185,7 +185,7 @@ module Mongrel
185
185
  def daemonize(options={})
186
186
  ops = resolve_defaults(options)
187
187
  # save this for later since daemonize will hose it
188
- if RUBY_PLATFORM !~ /mswin|mingw/
188
+ if RUBY_PLATFORM !~ /mingw|mswin/
189
189
  require 'daemons/daemonize'
190
190
 
191
191
  logfile = ops[:log_file]
@@ -344,7 +344,7 @@ module Mongrel
344
344
  # it reads it in and does an eval on the contents passing in the right
345
345
  # binding so they can put their own Configurator statements.
346
346
  def run_config(script)
347
- open(script) {|f| eval(f.read, proc {self}) }
347
+ open(script) {|f| eval(f.read, proc {self}.binding) }
348
348
  end
349
349
 
350
350
  # Sets up the standard signal handlers that are used on most Ruby
@@ -366,7 +366,7 @@ module Mongrel
366
366
  # clean up the pid file always
367
367
  at_exit { remove_pid_file }
368
368
 
369
- if RUBY_PLATFORM !~ /mswin|mingw/
369
+ if RUBY_PLATFORM !~ /mingw|mswin/
370
370
  # graceful shutdown
371
371
  trap("TERM") { log "TERM signal received."; stop }
372
372
  trap("USR1") { log "USR1 received, toggling $mongrel_debug_client to #{!$mongrel_debug_client}"; $mongrel_debug_client = !$mongrel_debug_client }
@@ -65,7 +65,7 @@ module Mongrel
65
65
  REQUEST_URI='REQUEST_URI'.freeze
66
66
  REQUEST_PATH='REQUEST_PATH'.freeze
67
67
 
68
- MONGREL_VERSION="1.1.5".freeze
68
+ MONGREL_VERSION = VERSION = "1.2.0.pre2".freeze
69
69
 
70
70
  MONGREL_TMP_BASE="mongrel".freeze
71
71
 
@@ -205,11 +205,11 @@ module Mongrel
205
205
  # test to see if this is a conditional request, and test if
206
206
  # the response would be identical to the last response
207
207
  same_response = case
208
- when modified_since && !last_response_time = Time.httpdate(modified_since) rescue nil : false
209
- when modified_since && last_response_time > Time.now : false
210
- when modified_since && mtime > last_response_time : false
211
- when none_match && none_match == '*' : false
212
- when none_match && !none_match.strip.split(/\s*,\s*/).include?(etag) : false
208
+ when modified_since && !last_response_time = Time.httpdate(modified_since) rescue nil then false
209
+ when modified_since && last_response_time > Time.now then false
210
+ when modified_since && mtime > last_response_time then false
211
+ when none_match && none_match == '*' then false
212
+ when none_match && !none_match.strip.split(/\s*,\s*/).include?(etag) then false
213
213
  else modified_since || none_match # validation successful if we get this far and at least one of the header exists
214
214
  end
215
215
 
@@ -93,7 +93,7 @@ module Mongrel
93
93
  STDERR.puts e.backtrace.join("\n")
94
94
  # any errors means we should delete the file, including if the file is dumped
95
95
  @socket.close rescue nil
96
- @body.delete if @body.class == Tempfile
96
+ @body.close! if @body.class == Tempfile
97
97
  @body = nil # signals that there was a problem
98
98
  end
99
99
  end
@@ -75,7 +75,10 @@ module Mongrel
75
75
  elsif @header_sent
76
76
  raise "You have already sent the request headers."
77
77
  else
78
- @header.out.truncate(0)
78
+ # XXX Dubious ( http://mongrel.rubyforge.org/ticket/19 )
79
+ @header.out.close
80
+ @header = HeaderOut.new(StringIO.new)
81
+
79
82
  @body.close
80
83
  @body = StringIO.new
81
84
  end
@@ -173,7 +173,7 @@ module Mongrel
173
173
  ops = resolve_defaults(options)
174
174
  setup_signals(options)
175
175
 
176
- if RUBY_PLATFORM !~ /mswin|mingw/
176
+ if RUBY_PLATFORM !~ /mingw|mswin/
177
177
  # rails reload
178
178
  trap("HUP") { log "HUP signal received."; reload! }
179
179
 
@@ -0,0 +1,28 @@
1
+ require 'hoe'
2
+
3
+ HOE = Hoe.spec 'mongrel' do
4
+ self.rubyforge_name = 'mongrel'
5
+ developer 'Zed A. Shaw', 'mongrel-users@rubyforge.org'
6
+
7
+ spec_extras[:required_ruby_version] = Gem::Requirement.new('>= 1.8.6')
8
+
9
+ spec_extras[:extensions] = ["ext/http11/extconf.rb"]
10
+ spec_extras[:executables] = ['mongrel_rails']
11
+
12
+ extra_rdoc_files << 'LICENSE'
13
+
14
+ extra_deps << ['gem_plugin', '~> 0.2.3']
15
+ extra_deps << ['daemons', '~> 1.0.10']
16
+
17
+ extra_dev_deps << ['rake-compiler', "~> 0.7.0"]
18
+
19
+ clean_globs.push('test_*.log', 'log')
20
+ end
21
+
22
+ file "#{HOE.spec.name}.gemspec" => ['Rakefile', 'tasks/gem.rake'] do |t|
23
+ puts "Generating #{t.name}"
24
+ File.open(t.name, 'w') { |f| f.puts HOE.spec.to_yaml }
25
+ end
26
+
27
+ desc "Generate or update the standalone gemspec file for the project"
28
+ task :gemspec => ["#{HOE.spec.name}.gemspec"]
@@ -0,0 +1,24 @@
1
+ # use rake-compiler for building the extension
2
+ require 'rake/extensiontask'
3
+
4
+ # build http11 C extension
5
+ Rake::ExtensionTask.new('http11', HOE.spec) do |ext|
6
+ # define target for extension (supporting fat binaries)
7
+ if RUBY_PLATFORM =~ /mingw|mswin/ then
8
+ RUBY_VERSION =~ /(\d+\.\d+)/
9
+ ext.lib_dir = "lib/#{$1}"
10
+ end
11
+
12
+ # define cross-compilation tasks when not on Windows.
13
+ unless RUBY_PLATFORM =~ /mingw|mswin/ then
14
+ ext.cross_compile = true
15
+ ext.cross_platform = ['i386-mswin32', 'i386-mingw32']
16
+
17
+ ext.cross_compiling do |gs|
18
+ gs.dependencies.delete gs.dependencies.find { |d| d.name == 'daemons' }
19
+ end
20
+ end
21
+ end
22
+
23
+ # ensure things are built prior testing
24
+ task :test => [:compile]
@@ -0,0 +1,20 @@
1
+
2
+ # the following tasks ease the build of C file from Ragel one
3
+
4
+ file 'ext/http11/http11_parser.c' => ['ext/http11/http11_parser.rl'] do |t|
5
+ begin
6
+ sh "ragel #{t.prerequisites.last} -C -G2 -o #{t.name}"
7
+ rescue
8
+ fail "Could not build wrapper using Ragel (it failed or not installed?)"
9
+ end
10
+ end
11
+
12
+ file 'ext/http11/org/jruby/mongrel/Http11Parser.java' => ['ext/http11/http11_parser.java.rl'] do |t|
13
+ begin
14
+ sh "ragel #{t.prerequisites.last} -J -G2 -o #{t.name}"
15
+ rescue
16
+ fail "Could not build wrapper using Ragel (it failed or not installed?)"
17
+ end
18
+ end
19
+
20
+ task :ragel => (defined?(JRUBY_VERSION) ? 'ext/http11/org/jruby/mongrel/Http11Parser.java' : 'ext/http11/http11_parser.c')
@@ -10,14 +10,14 @@ include Mongrel
10
10
 
11
11
  class ConditionalResponseTest < Test::Unit::TestCase
12
12
  def setup
13
- @server = HttpServer.new('127.0.0.1', process_based_port)
13
+ @server = HttpServer.new('127.0.0.1', 3501)
14
14
  @server.register('/', Mongrel::DirHandler.new('.'))
15
15
  @server.run
16
16
 
17
17
  @http = Net::HTTP.new(@server.host, @server.port)
18
18
 
19
19
  # get the ETag and Last-Modified headers
20
- @path = '/README'
20
+ @path = '/README.txt'
21
21
  res = @http.start { |http| http.get(@path) }
22
22
  assert_not_nil @etag = res['ETag']
23
23
  assert_not_nil @last_modified = res['Last-Modified']
@@ -30,11 +30,10 @@ class ConfiguratorTest < Test::Unit::TestCase
30
30
 
31
31
  def test_base_handler_config
32
32
  @config = nil
33
- @port = process_based_port
34
33
 
35
34
  redirect_test_io do
36
35
  @config = Mongrel::Configurator.new :host => "localhost" do
37
- listener :port => process_based_port do
36
+ listener :port => 4501 do
38
37
  # 2 in front should run, but the sentinel shouldn't since dirhandler processes the request
39
38
  uri "/", :handler => plugin("/handlers/testplugin")
40
39
  uri "/", :handler => plugin("/handlers/testplugin")
@@ -65,12 +64,12 @@ class ConfiguratorTest < Test::Unit::TestCase
65
64
  assert listener.classifier.uris.include?("/test"), "/test not registered"
66
65
  end
67
66
 
68
- res = Net::HTTP.get(URI.parse("http://localhost:#{@port}/test"))
67
+ res = Net::HTTP.get(URI.parse('http://localhost:4501/test'))
69
68
  assert res != nil, "Didn't get a response"
70
69
  assert $test_plugin_fired == 3, "Test filter plugin didn't run 3 times."
71
70
 
72
71
  redirect_test_io do
73
- res = Net::HTTP.get(URI.parse("http://localhost:#{@port}/"))
72
+ res = Net::HTTP.get(URI.parse('http://localhost:4501/'))
74
73
 
75
74
  assert res != nil, "Didn't get a response"
76
75
  assert $test_plugin_fired == 6, "Test filter plugin didn't run 6 times."
@@ -81,7 +80,7 @@ class ConfiguratorTest < Test::Unit::TestCase
81
80
  end
82
81
 
83
82
  assert_raise Errno::EBADF, Errno::ECONNREFUSED do
84
- res = Net::HTTP.get(URI.parse("http://localhost:#{@port}/"))
83
+ res = Net::HTTP.get(URI.parse("http://localhost:4501/"))
85
84
  end
86
85
  end
87
86
 
@@ -34,11 +34,10 @@ end
34
34
  class HandlersTest < Test::Unit::TestCase
35
35
 
36
36
  def setup
37
- @port = process_based_port
38
37
  stats = Mongrel::StatisticsFilter.new(:sample_rate => 1)
39
38
 
40
- @config = Mongrel::Configurator.new :host => '127.0.0.1' do
41
- listener :port => process_based_port do
39
+ @config = Mongrel::Configurator.new :host => '127.0.0.1', :port => 9998 do
40
+ listener do
42
41
  uri "/", :handler => SimpleHandler.new
43
42
  uri "/", :handler => stats
44
43
  uri "/404", :handler => Mongrel::Error404Handler.new("Not found")
@@ -51,10 +50,8 @@ class HandlersTest < Test::Unit::TestCase
51
50
  end
52
51
  end
53
52
 
54
- @test_file = windows? ? "testfile" : "tmp/testfile"
55
-
56
- File.open("/#{@test_file}", 'w') do
57
- # Do nothing
53
+ unless windows?
54
+ File.open("/tmp/testfile", 'w') { } # Do nothing
58
55
  end
59
56
 
60
57
  @config.run
@@ -62,40 +59,52 @@ class HandlersTest < Test::Unit::TestCase
62
59
 
63
60
  def teardown
64
61
  @config.stop(false, true)
65
- File.delete "/#{@test_file}"
62
+ File.delete "/tmp/testfile" unless windows?
63
+ end
64
+
65
+ def test_registration_exception_is_not_lost
66
+ assert_raises(Mongrel::URIClassifier::RegistrationError) do
67
+ @config = Mongrel::Configurator.new do
68
+ listener do
69
+ uri "bogus", :handler => SimpleHandler.new
70
+ end
71
+ end
72
+ end
66
73
  end
67
74
 
68
75
  def test_more_web_server
69
- res = hit([ "http://localhost:#{@port}/test",
70
- "http://localhost:#{@port}/dumb",
71
- "http://localhost:#{@port}/404",
72
- "http://localhost:#{@port}/files/rdoc/index.html",
73
- "http://localhost:#{@port}/files/rdoc/nothere.html",
74
- "http://localhost:#{@port}/files/rdoc/",
75
- "http://localhost:#{@port}/files_nodir/rdoc/",
76
- "http://localhost:#{@port}/status",
76
+ res = hit([ "http://localhost:9998/test",
77
+ "http://localhost:9998/dumb",
78
+ "http://localhost:9998/404",
79
+ "http://localhost:9998/files/rdoc/index.html",
80
+ "http://localhost:9998/files/rdoc/nothere.html",
81
+ "http://localhost:9998/files/rdoc/",
82
+ "http://localhost:9998/files_nodir/rdoc/",
83
+ "http://localhost:9998/status",
77
84
  ])
78
85
  check_status res, String
79
86
  end
80
87
 
81
88
  def test_nil_dirhandler
89
+ return if windows?
90
+
82
91
  # Camping uses this internally
83
92
  handler = Mongrel::DirHandler.new(nil, false)
84
- assert handler.can_serve("/#{@test_file}")
93
+ assert handler.can_serve("/tmp/testfile")
85
94
  # Not a bug! A nil @file parameter is the only circumstance under which
86
95
  # we are allowed to serve any existing file
87
- assert handler.can_serve("../../../../../../../../../../#{@test_file}")
96
+ assert handler.can_serve("../../../../../../../../../../tmp/testfile")
88
97
  end
89
98
 
90
99
  def test_non_nil_dirhandler_is_not_vulnerable_to_path_traversal
91
100
  # The famous security bug of Mongrel 1.1.2
92
101
  handler = Mongrel::DirHandler.new("/doc", false)
93
- assert_nil handler.can_serve("/#{@test_file}")
94
- assert_nil handler.can_serve("../../../../../../../../../../#{@test_file}")
102
+ assert_nil handler.can_serve("/tmp/testfile")
103
+ assert_nil handler.can_serve("../../../../../../../../../../tmp/testfile")
95
104
  end
96
105
 
97
106
  def test_deflate
98
- Net::HTTP.start("localhost", @port) do |h|
107
+ Net::HTTP.start("localhost", 9998) do |h|
99
108
  # Test that no accept-encoding returns a non-deflated response
100
109
  req = h.get("/dumb")
101
110
  assert(
@@ -113,14 +122,14 @@ class HandlersTest < Test::Unit::TestCase
113
122
 
114
123
  # TODO: find out why this fails on win32 but nowhere else
115
124
  #def test_posting_fails_dirhandler
116
- # req = Net::HTTP::Post.new("http://localhost:#{@port}/files/rdoc/")
125
+ # req = Net::HTTP::Post.new("http://localhost:9998/files/rdoc/")
117
126
  # req.set_form_data({'from'=>'2005-01-01', 'to'=>'2005-03-31'}, ';')
118
- # res = hit [["http://localhost:#{@port}/files/rdoc/",req]]
127
+ # res = hit [["http://localhost:9998/files/rdoc/",req]]
119
128
  # check_status res, Net::HTTPNotFound
120
129
  #end
121
130
 
122
131
  def test_unregister
123
- @config.listeners["127.0.0.1:#{@port}"].unregister("/")
132
+ @config.listeners["127.0.0.1:9998"].unregister("/")
124
133
  end
125
134
  end
126
135
 
@@ -9,12 +9,11 @@ require 'test/testhelp'
9
9
  class RedirectHandlerTest < Test::Unit::TestCase
10
10
 
11
11
  def setup
12
- @port = process_based_port
13
12
  redirect_test_io do
14
- @server = Mongrel::HttpServer.new('127.0.0.1', @port)
13
+ @server = Mongrel::HttpServer.new('127.0.0.1', 9998)
15
14
  end
16
15
  @server.run
17
- @client = Net::HTTP.new('127.0.0.1', @port)
16
+ @client = Net::HTTP.new('127.0.0.1', 9998)
18
17
  end
19
18
 
20
19
  def teardown
@@ -38,9 +38,8 @@ end
38
38
 
39
39
  class RequestProgressTest < Test::Unit::TestCase
40
40
  def setup
41
- @port = process_based_port
42
41
  redirect_test_io do
43
- @server = Mongrel::HttpServer.new("127.0.0.1", @port)
42
+ @server = Mongrel::HttpServer.new("127.0.0.1", 9998)
44
43
  end
45
44
  @handler = UploadBeginHandler.new
46
45
  @server.register("/upload", @handler)
@@ -52,7 +51,7 @@ class RequestProgressTest < Test::Unit::TestCase
52
51
  end
53
52
 
54
53
  def test_begin_end_progress
55
- Net::HTTP.get("localhost", "/upload", @port)
54
+ Net::HTTP.get("localhost", "/upload", 9998)
56
55
  assert @handler.request_began
57
56
  assert @handler.request_progressed
58
57
  assert @handler.request_processed
@@ -63,7 +62,7 @@ class RequestProgressTest < Test::Unit::TestCase
63
62
  handlers.each { |h| h.reset }
64
63
 
65
64
  # make the call
66
- Net::HTTP.get("localhost", "/upload", @port)
65
+ Net::HTTP.get("localhost", "/upload", 9998)
67
66
 
68
67
  # assert that each one was fired
69
68
  handlers.each { |h|
@@ -89,7 +88,7 @@ class RequestProgressTest < Test::Unit::TestCase
89
88
  # remove handlers to make sure they've all gone away
90
89
  @server.unregister("/upload")
91
90
  handlers.each { |h| h.reset }
92
- Net::HTTP.get("localhost", "/upload", @port)
91
+ Net::HTTP.get("localhost", "/upload", 9998)
93
92
  handlers.each { |h|
94
93
  assert !h.request_began && !h.request_progressed && !h.request_processed
95
94
  }