about summary refs log tree commit homepage
diff options
context:
space:
mode:
-rw-r--r--examples/simpletest.rb1
-rw-r--r--lib/mongrel.rb5
-rw-r--r--lib/mongrel/handlers.rb7
-rw-r--r--test/test_configurator.rb10
-rw-r--r--test/test_debug.rb2
-rw-r--r--test/test_http11.rb4
-rw-r--r--test/test_ws.rb104
7 files changed, 102 insertions, 31 deletions
diff --git a/examples/simpletest.rb b/examples/simpletest.rb
index 48ff1dc..df1ad56 100644
--- a/examples/simpletest.rb
+++ b/examples/simpletest.rb
@@ -1,7 +1,6 @@
 $LOAD_PATH << File.join(File.dirname(__FILE__), "..", "lib")
 require 'mongrel'
 require 'yaml'
-require 'zlib'
 
 class SimpleHandler < Mongrel::HttpHandler
   def process(request, response)
diff --git a/lib/mongrel.rb b/lib/mongrel.rb
index e013e5c..28c0dc4 100644
--- a/lib/mongrel.rb
+++ b/lib/mongrel.rb
@@ -264,7 +264,6 @@ module Mongrel
 
       return params
     end
-
   end
 
 
@@ -286,7 +285,6 @@ module Mongrel
     def[]=(key,value)
       @out.write(Const::HEADER_FORMAT % [key, value])
     end
-
   end
 
   # Writes and controls your response to the client using the HTTP/1.1 specification.
@@ -606,7 +604,6 @@ module Mongrel
               sleep @timeout/100 if @timeout > 0
             end
           rescue StopServer
-            STDERR.puts "Server stopped.  Exiting."
             @socket.close if not @socket.closed?
             break
           rescue Errno::EMFILE
@@ -909,7 +906,6 @@ module Mongrel
     # to prevent Ruby from exiting until each one is done.
     def run
       @listeners.each {|name,s|
-        log "Running #{name} listener."
         s.run
       }
 
@@ -922,7 +918,6 @@ module Mongrel
     # should be unlinked on exit.
     def stop(needs_restart=false, unlink_pid_file=true)
       @listeners.each {|name,s|
-        log "Stopping #{name} listener."
         s.stop
       }
 
diff --git a/lib/mongrel/handlers.rb b/lib/mongrel/handlers.rb
index b70568c..99aaeae 100644
--- a/lib/mongrel/handlers.rb
+++ b/lib/mongrel/handlers.rb
@@ -1,4 +1,5 @@
 require 'mongrel/stats'
+require 'zlib'
 
 # Mongrel Web Server - A Mostly Ruby Webserver and Library
 #
@@ -273,17 +274,21 @@ module Mongrel
   # When added to a config script (-S in mongrel_rails) it will
   # look at the client's allowed response types and then gzip
   # compress anything that is going out.
+  #
+  # Valid option is :always_deflate => false which tells the handler to
+  # deflate everything even if the client can't handle it.
   class DeflateFilter < HttpHandler
     HTTP_ACCEPT_ENCODING = "HTTP_ACCEPT_ENCODING"
 
     def initialize(ops={})
       @options = ops
+      @always_deflate = ops[:always_deflate] || false
     end
 
     def process(request, response)
       accepts = request.params[HTTP_ACCEPT_ENCODING]
       # only process if they support compression
-      if accepts and (accepts.include? "deflate" and not response.body_sent)
+      if @always_deflate or (accepts and (accepts.include? "deflate" and not response.body_sent))
         response.header["Content-Encoding"] = "deflate"
         # we can't just rewind the body and gzip it since the body could be an attached file
         response.body.rewind
diff --git a/test/test_configurator.rb b/test/test_configurator.rb
index 5a6ca79..dbea1a7 100644
--- a/test/test_configurator.rb
+++ b/test/test_configurator.rb
@@ -55,14 +55,20 @@ class ConfiguratorTest < Test::Unit::TestCase
         uri "/test", :handler => plugin("/handlers/testplugin")
         uri "/test", :handler => Mongrel::DirHandler.new(".")
         uri "/test", :handler => plugin("/handlers/testplugin")
+
+        debug "/"
+        setup_signals
+
+        run_config(File.dirname(__FILE__) + "/../test/mongrel.conf")
+        load_mime_map(File.dirname(__FILE__) + "/../examples/mime.yaml")
+
         run
       end
     end
 
 
     config.listeners.each do |host,listener|
-      puts "Registered URIs: #{listener.classifier.uris.inspect}"
-      assert listener.classifier.uris.length == 2, "Wrong number of registered URIs"
+      assert listener.classifier.uris.length == 3, "Wrong number of registered URIs"
       assert listener.classifier.uris.include?("/"),  "/ not registered"
       assert listener.classifier.uris.include?("/test"), "/test not registered"
     end
diff --git a/test/test_debug.rb b/test/test_debug.rb
index ad9674a..58cdfdd 100644
--- a/test/test_debug.rb
+++ b/test/test_debug.rb
@@ -40,8 +40,6 @@ class MongrelDbgTest < Test::Unit::TestCase
     MongrelDbg::end_trace(:rails)
 
     assert File.exist?("log/mongrel_debug"), "Didn't make logging directory"
-    assert File.exist?("log/mongrel_debug/rails.log"), "Didn't make the rails.log file"
-    assert File.size("log/mongrel_debug/rails.log") > 0, "Didn't write anything to the log."
   end
 
 end
diff --git a/test/test_http11.rb b/test/test_http11.rb
index cd6e5bf..bf8276a 100644
--- a/test/test_http11.rb
+++ b/test/test_http11.rb
@@ -124,11 +124,11 @@ class HttpParserTest < Test::Unit::TestCase
 
 
   def test_query_parse
-    res = HttpRequest.query_parse("zed=1&frank=2")
+    res = HttpRequest.query_parse("zed=1&frank=#{HttpRequest.escape('&&& ')}")
     assert res["zed"], "didn't get the request right"
     assert res["frank"], "no frank"
     assert_equal "1", res["zed"], "wrong result"
-    assert_equal "2", res["frank"], "wrong result"
+    assert_equal "&&& ", HttpRequest.unescape(res["frank"]), "wrong result"
 
     res = HttpRequest.query_parse("zed=1&zed=2&zed=3&frank=11;zed=45")
     assert res["zed"], "didn't get the request right"
diff --git a/test/test_ws.rb b/test/test_ws.rb
index 47060fb..daf78d6 100644
--- a/test/test_ws.rb
+++ b/test/test_ws.rb
@@ -21,31 +21,99 @@ require 'net/http'
 require 'mongrel'
 require 'timeout'
 
-include Mongrel;
+
 
 class TestHandler < Mongrel::HttpHandler
-    attr_reader :ran_test
-    
-    def process(request, response)
-        @ran_test = true
-        response.socket.write("HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\nhello!\n")
-    end
+  attr_reader :ran_test
+
+  def process(request, response)
+    @ran_test = true
+    response.socket.write("HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\nhello!\n")
+  end
+end
+
+def hit(uris)
+  uris.each do |u|
+    res = Net::HTTP.get(URI.parse(u))
+    assert res != nil, "Didn't get a response: #{u}"
+  end
 end
-                
 
-class WSTest < Test::Unit::TestCase
+class WebServerTest < Test::Unit::TestCase
 
-    def test_simple_server
-        h = HttpServer.new("127.0.0.1", 9998)
-        tester = TestHandler.new
-        h.register("/test", tester)
-        h.run
+  def setup
+    @request = "GET / HTTP/1.1\r\nHost: www.zedshaw.com\r\nContent-Type: text/plain\r\n\r\n"
+    # we set num_processors=1 so that we can test the reaping code
+    @server = HttpServer.new("127.0.0.1", 9998,num_processors=1)
+    @tester = TestHandler.new
+    @server.register("/test", @tester)
+    @server.run
+  end
 
-        sleep(3)
-        res = Net::HTTP.get(URI.parse('http://localhost:9998/test'))
-        assert res != nil, "Didn't get a response"
-        assert tester.ran_test, "Handler didn't really run"
+  def teardown
+    @server.stop
+  end
+
+  def test_simple_server
+    hit(['http://localhost:9998/test'])
+    assert @tester.ran_test, "Handler didn't really run"
+  end
+
+
+  def do_test(st, chunk, close_after=nil)
+    s = TCPSocket.new("127.0.0.1", 9998);
+    req = StringIO.new(st)
+    nout = 0
+
+    while data = req.read(chunk)
+      nout += s.write(data)
+      s.flush
+      sleep 0.2
+      if close_after and nout > close_after
+        s.close_write
+        sleep 1
+      end
     end
+    s.close
+  end
+
+  def test_trickle_attack
+    do_test(@request, 3)
+  end
+
+  def test_close_client
+    assert_raises IOError do
+      do_test(@request, 10, 20)
+    end
+  end
+
+  def test_bad_client
+    do_test("GET /test HTTP/BAD", 3)
+  end
+
+  def test_header_is_too_long
+    long = "GET /test HTTP/1.1\r\n" + ("X-Big: stuff\r\n" * 15000) + "\r\n"
+    assert_raises Errno::ECONNRESET, Errno::EPIPE do
+      do_test(long, long.length/2)
+    end
+  end
+
+  def test_num_processors_overload
+    assert_raises Errno::ECONNRESET, Errno::EPIPE do
+      tests = [
+        Thread.new { do_test(@request, 1) },
+        Thread.new { do_test(@request, 10) },
+      ]
+
+      tests.each {|t| t.join}
+    end
+  end
+
+  def test_file_streamed_request
+    body = "a" * (Mongrel::Const::MAX_BODY * 2)
+    long = "GET /test HTTP/1.1\r\nContent-length: #{body.length}\r\n\r\n" + body
+    do_test(long, Mongrel::Const::CHUNK_SIZE * 2 -400)
+  end
 
 end