[Mongrel] [PATCH] HTTP accept filter support for FreeBSD

Thomas Hurst tom at hur.st
Sat Nov 25 05:52:33 EST 2006


This small patch extends configure_socket_options to support FreeBSD's
accf_http(9), which defers accept() until there's a full HTTP request
to read.

Seems to work fine on 6.1-STABLE.  DragonflyBSD should work too provided
the /freebsd/ line is modified to match it.


 accf_http(9): http://www.freebsd.org/cgi/man.cgi?query=accf_http&sektion=9

-- 
Thomas 'Freaky' Hurst
    http://hur.st/
-------------- next part --------------
--- mongrel.rb.orig	Sat Nov 25 05:19:12 2006
+++ mongrel.rb	Sat Nov 25 08:41:20 2006
@@ -666,10 +666,17 @@
     end
 
     def configure_socket_options
-      if /linux/ === RUBY_PLATFORM
+      case RUBY_PLATFORM
+      when /linux/
         # 9 is currently TCP_DEFER_ACCEPT
-        $tcp_defer_accept_opts = [9,1]
-        $tcp_cork_opts = [3,1]
+        $tcp_defer_accept_opts = [Socket::SOL_TCP, 9, 1]
+        $tcp_cork_opts = [Socket::SOL_TCP, 3, 1]
+      when /freebsd/
+        # Use the HTTP accept filter if available.
+        # The struct made by pack() is defined in /usr/include/sys/socket.h as accept_filter_arg
+        unless `/sbin/sysctl -nq net.inet.accf.http`.empty?
+          $tcp_defer_accept_opts = [Socket::SOL_SOCKET, Socket::SO_ACCEPTFILTER, ['httpready', nil].pack('a16a240')]
+        end
       end
     end
 
@@ -680,13 +687,13 @@
 
       configure_socket_options
 
-      @socket.setsockopt(Socket::SOL_TCP, $tcp_defer_accept_opts[0], $tcp_defer_accept_opts[1]) if $tcp_defer_accept_opts
+      @socket.setsockopt(*$tcp_defer_accept_opts) if $tcp_defer_accept_opts
 
       @acceptor = Thread.new do
         while true
           begin
             client = @socket.accept
-            client.setsockopt(Socket::SOL_TCP, $tcp_cork_opts[0], $tcp_cork_opts[1]) if $tcp_cork_opts
+            client.setsockopt(*$tcp_cork_opts) if $tcp_cork_opts
 
             worker_list = @workers.list
 


More information about the Mongrel-users mailing list