about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2011-05-09 04:39:54 +0000
committerEric Wong <normalperson@yhbt.net>2011-05-10 08:20:27 +0000
commit704f843054f3ca32941d42972a1c7d1b144d06ad (patch)
tree2e7fea212988a9a67b7cdfab3ef939a221448e65
parent598525843ee1d120fd9878011ca2b6328c2cf95f (diff)
downloadrainbows-704f843054f3ca32941d42972a1c7d1b144d06ad.tar.gz
There's actually no reason we can't have these methods
in Rainbows::Configurator where it's easier to document
nowadays.
-rw-r--r--lib/rainbows.rb22
-rw-r--r--lib/rainbows/client.rb7
-rw-r--r--lib/rainbows/configurator.rb79
-rw-r--r--lib/rainbows/coolio.rb2
-rw-r--r--lib/rainbows/coolio/client.rb4
-rw-r--r--lib/rainbows/coolio/heartbeat.rb3
-rw-r--r--lib/rainbows/coolio_fiber_spawn.rb1
-rw-r--r--lib/rainbows/epoll/client.rb4
-rw-r--r--lib/rainbows/ev_core.rb4
-rw-r--r--lib/rainbows/event_machine/client.rb3
-rw-r--r--lib/rainbows/fiber/base.rb1
-rw-r--r--lib/rainbows/fiber/coolio/methods.rb1
-rw-r--r--lib/rainbows/fiber/io.rb1
-rw-r--r--lib/rainbows/http_server.rb76
-rw-r--r--lib/rainbows/max_body.rb11
-rw-r--r--lib/rainbows/process_client.rb4
-rw-r--r--lib/rainbows/response.rb2
-rw-r--r--lib/rainbows/revactor/client.rb4
-rw-r--r--lib/rainbows/xepoll_thread_pool/client.rb6
-rw-r--r--lib/rainbows/xepoll_thread_spawn/client.rb8
-rw-r--r--t/client_header_buffer_size.ru4
21 files changed, 140 insertions, 107 deletions
diff --git a/lib/rainbows.rb b/lib/rainbows.rb
index da7011a..18c9b06 100644
--- a/lib/rainbows.rb
+++ b/lib/rainbows.rb
@@ -68,30 +68,20 @@ module Rainbows
 
   # :stopdoc:
   class << self
-    attr_accessor :client_header_buffer_size
-    attr_accessor :client_max_body_size
-    attr_accessor :keepalive_timeout
     attr_accessor :server
     attr_accessor :cur # may not always be used
     attr_reader :alive
     attr_writer :tick_io
+    attr_writer :forked
   end
-  # :startdoc:
-
-  def self.defaults!
-    # the default max body size is 1 megabyte (1024 * 1024 bytes)
-    @client_max_body_size = 1024 * 1024
-
-    # the default keepalive_timeout is 5 seconds
-    @keepalive_timeout = 5
 
-    # 1024 bytes matches nginx, though Rails session cookies will typically
-    # need >= 1500...
-    @client_header_buffer_size = 1024
+  def self.config!(mod, *opts)
+    @forked or abort "#{mod} should only be loaded in a worker process"
+    opts.each do |opt|
+      mod.const_set(opt.to_s.upcase, Rainbows.server.__send__(opt))
+    end
   end
 
-  defaults!
-
   # :stopdoc:
   @alive = true
   @cur = 0
diff --git a/lib/rainbows/client.rb b/lib/rainbows/client.rb
index 4608f53..b044f26 100644
--- a/lib/rainbows/client.rb
+++ b/lib/rainbows/client.rb
@@ -5,20 +5,21 @@ require "io/wait"
 # this class is used for most synchronous concurrency models
 class Rainbows::Client < Kgio::Socket
   include Rainbows::ProcessClient
+  Rainbows.config!(self, :keepalive_timeout)
 
   def read_expire
-    Time.now + Rainbows.keepalive_timeout
+    Time.now + KEEPALIVE_TIMEOUT
   end
 
   def kgio_wait_readable
-    wait Rainbows.keepalive_timeout
+    wait KEEPALIVE_TIMEOUT
   end
 
   # used for reading headers (respecting keepalive_timeout)
   def timed_read(buf)
     expire = nil
     begin
-      case rv = kgio_tryread(HBUFSIZ, buf)
+      case rv = kgio_tryread(CLIENT_HEADER_BUFFER_SIZE, buf)
       when :wait_readable
         return if expire && expire < Time.now
         expire ||= read_expire
diff --git a/lib/rainbows/configurator.rb b/lib/rainbows/configurator.rb
index b596b0b..95bb590 100644
--- a/lib/rainbows/configurator.rb
+++ b/lib/rainbows/configurator.rb
@@ -3,6 +3,14 @@
 # This module adds \Rainbows! to the
 # {Unicorn::Configurator}[http://unicorn.bogomips.org/Unicorn/Configurator.html]
 module Rainbows::Configurator
+  Unicorn::Configurator::DEFAULTS.merge!({
+    :use => Rainbows::Base,
+    :worker_connections => 50,
+    :keepalive_timeout => 5,
+    :keepalive_requests => 100,
+    :client_max_body_size => 1024 * 1024,
+    :client_header_buffer_size => 1024,
+  })
 
   # configures \Rainbows! with a given concurrency model to +use+ and
   # a +worker_connections+ upper-bound.  This method may be called
@@ -45,7 +53,76 @@ module Rainbows::Configurator
   # denial-of-service attacks that use HTTP pipelining.
   def Rainbows!(&block)
     block_given? or raise ArgumentError, "Rainbows! requires a block"
-    Rainbows::HttpServer.setup(block)
+    @block = true
+    instance_eval(&block)
+    ensure
+      @block = false
+  end
+
+  def check! # :nodoc:
+    @block or abort "must be inside a Rainbows! block"
+  end
+
+  def worker_connections(nr)
+    check!
+    set_int(:worker_connections, nr, 1)
+  end
+
+  def use(model, *options)
+    check!
+    mod = begin
+      Rainbows.const_get(model)
+    rescue NameError => e
+      warn "error loading #{model.inspect}: #{e}"
+      e.backtrace.each { |l| warn l }
+      abort "concurrency model #{model.inspect} not supported"
+    end
+    Module === mod or abort "concurrency model #{model.inspect} not supported"
+    options.each do |opt|
+      case opt
+      when Hash
+        Rainbows::O.merge!(opt)
+      when Symbol
+        Rainbows::O[opt] = true
+      else
+        abort "cannot handle option: #{opt.inspect} in #{options.inspect}"
+      end
+    end
+    mod.setup if mod.respond_to?(:setup)
+    set[:use] = mod
+  end
+
+  def keepalive_timeout(seconds)
+    check!
+    set_int(:keepalive_timeout, seconds, 0)
+  end
+
+  def keepalive_requests(count)
+    check!
+    case count
+    when nil, Integer
+      set[:keepalive_requests] = count
+    else
+      abort "not an integer or nil: keepalive_requests=#{count.inspect}"
+    end
+  end
+
+  def client_max_body_size(bytes)
+    check!
+    err = "client_max_body_size must be nil or a non-negative Integer"
+    case bytes
+    when nil
+    when Integer
+      bytes >= 0 or abort err
+    else
+      abort err
+    end
+    set[:client_max_body_size] = bytes
+  end
+
+  def client_header_buffer_size(bytes)
+    check!
+    set_int(:client_header_buffer_size, bytes, 1)
   end
 end
 
diff --git a/lib/rainbows/coolio.rb b/lib/rainbows/coolio.rb
index 59bfde6..b62e02b 100644
--- a/lib/rainbows/coolio.rb
+++ b/lib/rainbows/coolio.rb
@@ -39,10 +39,10 @@ module Rainbows::Coolio
   autoload :ThreadClient, 'rainbows/coolio/thread_client'
   autoload :ResponsePipe, 'rainbows/coolio/response_pipe'
   autoload :ResponseChunkPipe, 'rainbows/coolio/response_chunk_pipe'
+  autoload :Heartbeat, 'rainbows/coolio/heartbeat'
   # :startdoc:
 end
 # :enddoc:
-require 'rainbows/coolio/heartbeat'
 require 'rainbows/coolio/server'
 require 'rainbows/coolio/core'
 Rainbows::Coolio.__send__ :include, Rainbows::Coolio::Core
diff --git a/lib/rainbows/coolio/client.rb b/lib/rainbows/coolio/client.rb
index 5688730..5d2edec 100644
--- a/lib/rainbows/coolio/client.rb
+++ b/lib/rainbows/coolio/client.rb
@@ -45,7 +45,7 @@ class Rainbows::Coolio::Client < Coolio::IO
   end
 
   def on_readable
-    buf = @_io.kgio_tryread(HBUFSIZ, RBUF)
+    buf = @_io.kgio_tryread(CLIENT_HEADER_BUFFER_SIZE, RBUF)
     case buf
     when :wait_readable
     when nil # eof
@@ -134,7 +134,7 @@ class Rainbows::Coolio::Client < Coolio::IO
       close if @_write_buffer.empty?
     when :headers
       if @buf.empty?
-        buf = @_io.kgio_tryread(HBUFSIZ, RBUF) or return close
+        buf = @_io.kgio_tryread(CLIENT_HEADER_BUFFER_SIZE, RBUF) or return close
         String === buf and return on_read(buf)
         # buf == :wait_readable
         unless enabled?
diff --git a/lib/rainbows/coolio/heartbeat.rb b/lib/rainbows/coolio/heartbeat.rb
index 4657155..f58ed33 100644
--- a/lib/rainbows/coolio/heartbeat.rb
+++ b/lib/rainbows/coolio/heartbeat.rb
@@ -8,9 +8,10 @@
 class Rainbows::Coolio::Heartbeat < Coolio::TimerWatcher
   KATO = Rainbows::Coolio::KATO
   CONN = Rainbows::Coolio::CONN
+  Rainbows.config!(self, :keepalive_timeout)
 
   def on_timer
-    if (ot = Rainbows.keepalive_timeout) >= 0
+    if (ot = KEEPALIVE_TIMEOUT) >= 0
       ot = Time.now - ot
       KATO.delete_if { |client, time| time < ot and client.timeout? }
     end
diff --git a/lib/rainbows/coolio_fiber_spawn.rb b/lib/rainbows/coolio_fiber_spawn.rb
index 7b00d58..88583f8 100644
--- a/lib/rainbows/coolio_fiber_spawn.rb
+++ b/lib/rainbows/coolio_fiber_spawn.rb
@@ -25,6 +25,7 @@ module Rainbows::CoolioFiberSpawn
     Server.const_set(:APP, Rainbows.server.app)
     Heartbeat.new(1, true).attach(Coolio::Loop.default)
     LISTENERS.map! { |s| Server.new(s).attach(Coolio::Loop.default) }
+    Rainbows::Client.__send__ :include, Rainbows::Fiber::Coolio::Methods
     Coolio::Loop.default.run
   end
 end
diff --git a/lib/rainbows/epoll/client.rb b/lib/rainbows/epoll/client.rb
index 520eb2b..0d6a8c0 100644
--- a/lib/rainbows/epoll/client.rb
+++ b/lib/rainbows/epoll/client.rb
@@ -10,7 +10,7 @@ module Rainbows::Epoll::Client
   OUT = SleepyPenguin::Epoll::OUT | SleepyPenguin::Epoll::ET
   KATO = {}
   KATO.compare_by_identity if KATO.respond_to?(:compare_by_identity)
-  KEEPALIVE_TIMEOUT = Rainbows.keepalive_timeout
+  Rainbows.config!(self, :keepalive_timeout)
   EP = Rainbows::Epoll::EP
   @@last_expire = Time.now
 
@@ -33,7 +33,7 @@ module Rainbows::Epoll::Client
   end
 
   def on_readable
-    case rv = kgio_tryread(HBUFSIZ, RBUF)
+    case rv = kgio_tryread(CLIENT_HEADER_BUFFER_SIZE, RBUF)
     when String
       on_read(rv)
       return if @wr_queue[0] || closed?
diff --git a/lib/rainbows/ev_core.rb b/lib/rainbows/ev_core.rb
index fb19b04..030c8e1 100644
--- a/lib/rainbows/ev_core.rb
+++ b/lib/rainbows/ev_core.rb
@@ -9,7 +9,7 @@ module Rainbows::EvCore
   autoload :CapInput, 'rainbows/ev_core/cap_input'
   RBUF = ""
   Z = "".freeze
-  HBUFSIZ = Rainbows.client_header_buffer_size
+  Rainbows.config!(self, :client_header_buffer_size)
 
   # Apps may return this Rack response: AsyncResponse = [ -1, {}, [] ]
   ASYNC_CALLBACK = "async.callback".freeze
@@ -133,7 +133,7 @@ module Rainbows::EvCore
   end
 
   def mkinput
-    max = Rainbows.client_max_body_size
+    max = Rainbows.server.client_max_body_size
     len = @hp.content_length
     if len
       if max && (len > max)
diff --git a/lib/rainbows/event_machine/client.rb b/lib/rainbows/event_machine/client.rb
index 8c2549d..e56931f 100644
--- a/lib/rainbows/event_machine/client.rb
+++ b/lib/rainbows/event_machine/client.rb
@@ -2,6 +2,7 @@
 # :enddoc:
 class Rainbows::EventMachine::Client < EM::Connection
   include Rainbows::EvCore
+  Rainbows.config!(self, :keepalive_timeout)
 
   def initialize(io)
     @_io = io
@@ -87,7 +88,7 @@ class Rainbows::EventMachine::Client < EM::Connection
     if alive
       if @deferred.nil?
         if @buf.empty?
-          set_comm_inactivity_timeout(Rainbows.keepalive_timeout)
+          set_comm_inactivity_timeout(KEEPALIVE_TIMEOUT)
         else
           EM.next_tick { receive_data(nil) }
         end
diff --git a/lib/rainbows/fiber/base.rb b/lib/rainbows/fiber/base.rb
index a4f2341..00af214 100644
--- a/lib/rainbows/fiber/base.rb
+++ b/lib/rainbows/fiber/base.rb
@@ -64,6 +64,7 @@ module Rainbows::Fiber::Base
   end
 
   def self.setup(klass, app)
+    Rainbows::Client.__send__(:include, Rainbows::Fiber::IO::Methods)
     require 'rainbows/fiber/body'
     Rainbows::Client.__send__(:include, Rainbows::Fiber::Body)
     self.const_set(:APP, app)
diff --git a/lib/rainbows/fiber/coolio/methods.rb b/lib/rainbows/fiber/coolio/methods.rb
index 64b0ee6..2e664ff 100644
--- a/lib/rainbows/fiber/coolio/methods.rb
+++ b/lib/rainbows/fiber/coolio/methods.rb
@@ -38,7 +38,6 @@ end
 
 [
   Rainbows::Fiber::IO,
-  Rainbows::Client,
   # the next two trigger autoload, ugh, oh well...
   Rainbows::Fiber::IO::Socket,
   Rainbows::Fiber::IO::Pipe
diff --git a/lib/rainbows/fiber/io.rb b/lib/rainbows/fiber/io.rb
index 3005d96..0eed4ad 100644
--- a/lib/rainbows/fiber/io.rb
+++ b/lib/rainbows/fiber/io.rb
@@ -101,7 +101,6 @@ end
 # :stopdoc:
 require 'rainbows/fiber/io/methods'
 require 'rainbows/fiber/io/compat'
-Rainbows::Client.__send__(:include, Rainbows::Fiber::IO::Methods)
 class Rainbows::Fiber::IO
   include Rainbows::Fiber::IO::Compat
   include Rainbows::Fiber::IO::Methods
diff --git a/lib/rainbows/http_server.rb b/lib/rainbows/http_server.rb
index 8732e68..62a5927 100644
--- a/lib/rainbows/http_server.rb
+++ b/lib/rainbows/http_server.rb
@@ -2,6 +2,12 @@
 # :enddoc:
 
 class Rainbows::HttpServer < Unicorn::HttpServer
+  attr_accessor :worker_connections
+  attr_accessor :keepalive_timeout
+  attr_accessor :client_header_buffer_size
+  attr_accessor :client_max_body_size
+  attr_reader :use
+
   def self.setup(block)
     Rainbows.server.instance_eval(&block)
   end
@@ -10,7 +16,7 @@ class Rainbows::HttpServer < Unicorn::HttpServer
     Rainbows.server = self
     @logger = Unicorn::Configurator::DEFAULTS[:logger]
     super(app, options)
-    defined?(@use) or use(:Base)
+    defined?(@use) or self.use = Rainbows::Base
     @worker_connections ||= @use == :Base ? 1 : 50
   end
 
@@ -33,14 +39,12 @@ class Rainbows::HttpServer < Unicorn::HttpServer
   end
 
   def load_config!
-    use :Base
-    Rainbows.defaults!
-    @worker_connections = nil
     super
-    @worker_connections ||= @use == :Base ? 1 : 50
+    @worker_connections = 1 if @use == :Base
   end
 
   def worker_loop(worker)
+    Rainbows.forked = true
     orig = method(:worker_loop)
     extend(Rainbows.const_get(@use))
     m = method(:worker_loop)
@@ -80,70 +84,22 @@ class Rainbows::HttpServer < Unicorn::HttpServer
     File.basename($0)
   end
 
-  def use(*args)
-    model = args.shift or return @use
-    mod = begin
-      Rainbows.const_get(model)
-    rescue NameError => e
-      logger.error "error loading #{model.inspect}: #{e}"
-      e.backtrace.each { |l| logger.error l }
-      raise ArgumentError, "concurrency model #{model.inspect} not supported"
-    end
-
-    Module === mod or
-      raise ArgumentError, "concurrency model #{model.inspect} not supported"
-    args.each do |opt|
-      case opt
-      when Hash; Rainbows::O.update(opt)
-      when Symbol; Rainbows::O[opt] = true
-      else; raise ArgumentError, "can't handle option: #{opt.inspect}"
-      end
-    end
-    mod.setup if mod.respond_to?(:setup)
+  def use=(mod)
+    @use = mod.to_s.split(/::/)[-1].to_sym
     new_defaults = {
-      'rainbows.model' => (@use = model.to_sym),
-      'rack.multithread' => !!(model.to_s =~ /Thread/),
+      'rainbows.model' => @use,
+      'rack.multithread' => !!(mod.to_s =~ /Thread/),
       'rainbows.autochunk' => [:Coolio,:Rev,:Epoll,:XEpoll,
                                :EventMachine,:NeverBlock].include?(@use),
     }
     Rainbows::Const::RACK_DEFAULTS.update(new_defaults)
   end
 
-  def worker_connections(*args)
-    return @worker_connections if args.empty?
-    nr = args[0]
-    (Integer === nr && nr > 0) or
-      raise ArgumentError, "worker_connections must be a positive Integer"
-    @worker_connections = nr
-  end
-
-  def keepalive_timeout(nr)
-    (Integer === nr && nr >= 0) or
-      raise ArgumentError, "keepalive_timeout must be a non-negative Integer"
-    Rainbows.keepalive_timeout = nr
-  end
-
-  def keepalive_requests(nr)
-    Integer === nr or
-      raise ArgumentError, "keepalive_requests must be a non-negative Integer"
+  def keepalive_requests=(nr)
     Unicorn::HttpRequest.keepalive_requests = nr
   end
 
-  def client_max_body_size(nr)
-    err = "client_max_body_size must be nil or a non-negative Integer"
-    case nr
-    when nil
-    when Integer
-      nr >= 0 or raise ArgumentError, err
-    else
-      raise ArgumentError, err
-    end
-    Rainbows.client_max_body_size = nr
-  end
-
-  def client_header_buffer_size(bytes)
-    Integer === bytes && bytes > 0 or raise ArgumentError,
-            "client_header_buffer_size must be a positive Integer"
-    Rainbows.client_header_buffer_size = bytes
+  def keepalive_requests
+    Unicorn::HttpRequest.keepalive_requests
   end
 end
diff --git a/lib/rainbows/max_body.rb b/lib/rainbows/max_body.rb
index 33ba572..aedc9e9 100644
--- a/lib/rainbows/max_body.rb
+++ b/lib/rainbows/max_body.rb
@@ -21,8 +21,12 @@
 class Rainbows::MaxBody
 
   # This is automatically called when used with Rack::Builder#use
-  def initialize(app, limit = Rainbows.client_max_body_size)
-    Integer === limit or raise ArgumentError, "limit not an Integer"
+  def initialize(app, limit = nil)
+    case limit
+    when Integer, nil
+    else
+      raise ArgumentError, "limit not an Integer"
+    end
     @app, @limit = app, limit
   end
 
@@ -33,6 +37,7 @@ class Rainbows::MaxBody
 
   # our main Rack middleware endpoint
   def call(env)
+    @limit = Rainbows.server.client_max_body_size if nil == @limit
     catch(:rainbows_EFBIG) do
       len = env[CONTENT_LENGTH]
       if len && len.to_i > @limit
@@ -47,7 +52,7 @@ class Rainbows::MaxBody
   # this is called after forking, so it won't ever affect the master
   # if it's reconfigured
   def self.setup # :nodoc:
-    Rainbows.client_max_body_size or return
+    Rainbows.server.client_max_body_size or return
     case Rainbows.server.use
     when :Rev, :Coolio, :EventMachine, :NeverBlock,
          :RevThreadSpawn, :RevThreadPool,
diff --git a/lib/rainbows/process_client.rb b/lib/rainbows/process_client.rb
index 3f23825..53b4f53 100644
--- a/lib/rainbows/process_client.rb
+++ b/lib/rainbows/process_client.rb
@@ -7,11 +7,11 @@ module Rainbows::ProcessClient
   NULL_IO = Unicorn::HttpRequest::NULL_IO
   RACK_INPUT = Unicorn::HttpRequest::RACK_INPUT
   IC = Unicorn::HttpRequest.input_class
-  HBUFSIZ = Rainbows.client_header_buffer_size
+  Rainbows.config!(self, :client_header_buffer_size)
 
   def process_loop
     @hp = hp = Rainbows::HttpParser.new
-    kgio_read!(HBUFSIZ, buf = hp.buf) or return
+    kgio_read!(CLIENT_HEADER_BUFFER_SIZE, buf = hp.buf) or return
 
     begin # loop
       until env = hp.parse
diff --git a/lib/rainbows/response.rb b/lib/rainbows/response.rb
index 576ff8d..65599e9 100644
--- a/lib/rainbows/response.rb
+++ b/lib/rainbows/response.rb
@@ -14,7 +14,7 @@ module Rainbows::Response
   # called after forking
   def self.setup(klass)
     Kgio.accept_class = Rainbows::Client
-    0 == Rainbows.keepalive_timeout and
+    0 == Rainbows.server.keepalive_timeout and
       Rainbows::HttpParser.keepalive_requests = 0
   end
 
diff --git a/lib/rainbows/revactor/client.rb b/lib/rainbows/revactor/client.rb
index c587589..c1cb7aa 100644
--- a/lib/rainbows/revactor/client.rb
+++ b/lib/rainbows/revactor/client.rb
@@ -4,8 +4,8 @@ require 'fcntl'
 class Rainbows::Revactor::Client
   autoload :TeeSocket, 'rainbows/revactor/client/tee_socket'
   RD_ARGS = {}
-  Rainbows.keepalive_timeout > 0 and
-    RD_ARGS[:timeout] = Rainbows.keepalive_timeout
+  Rainbows.server.keepalive_timeout > 0 and
+    RD_ARGS[:timeout] = Rainbows.server.keepalive_timeout
   attr_reader :kgio_addr
 
   def initialize(client)
diff --git a/lib/rainbows/xepoll_thread_pool/client.rb b/lib/rainbows/xepoll_thread_pool/client.rb
index 1bfb1c2..f871e56 100644
--- a/lib/rainbows/xepoll_thread_pool/client.rb
+++ b/lib/rainbows/xepoll_thread_pool/client.rb
@@ -3,7 +3,7 @@
 # FIXME: lots of duplication from xepolll_thread_spawn/client
 
 module Rainbows::XEpollThreadPool::Client
-  HBUFSIZ = Rainbows.client_header_buffer_size
+  Rainbows.config!(self, :keepalive_timeout, :client_header_buffer_size)
   N = Raindrops.new(1)
   ACCEPTORS = Rainbows::HttpServer::LISTENERS.dup
   extend Rainbows::WorkerYield
@@ -66,7 +66,7 @@ module Rainbows::XEpollThreadPool::Client
 
   def self.expire
     return if ((now = Time.now) - @@last_expire) < 1.0
-    if (ot = Rainbows.keepalive_timeout) >= 0
+    if (ot = KEEPALIVE_TIMEOUT) >= 0
       ot = now - ot
       defer = []
       LOCK.synchronize do
@@ -101,7 +101,7 @@ module Rainbows::XEpollThreadPool::Client
   end
 
   def epoll_run(buf)
-    case kgio_tryread(HBUFSIZ, buf)
+    case kgio_tryread(CLIENT_HEADER_BUFFER_SIZE, buf)
     when :wait_readable
       return kato_set
     when String
diff --git a/lib/rainbows/xepoll_thread_spawn/client.rb b/lib/rainbows/xepoll_thread_spawn/client.rb
index 049d4e1..f8fc191 100644
--- a/lib/rainbows/xepoll_thread_spawn/client.rb
+++ b/lib/rainbows/xepoll_thread_spawn/client.rb
@@ -1,7 +1,7 @@
 # -*- encoding: binary -*-
 # :stopdoc:
 module Rainbows::XEpollThreadSpawn::Client
-  HBUFSIZ = Rainbows.client_header_buffer_size
+  Rainbows.config!(self, :keepalive_timeout, :client_header_buffer_size)
   N = Raindrops.new(1)
   ACCEPTORS = Rainbows::HttpServer::LISTENERS.dup
   extend Rainbows::WorkerYield
@@ -55,7 +55,7 @@ module Rainbows::XEpollThreadSpawn::Client
 
   def self.expire
     return if ((now = Time.now) - @@last_expire) < 1.0
-    if (ot = Rainbows.keepalive_timeout) >= 0
+    if (ot = KEEPALIVE_TIMEOUT) >= 0
       ot = now - ot
       defer = []
       LOCK.synchronize do
@@ -85,7 +85,7 @@ module Rainbows::XEpollThreadSpawn::Client
   end
 
   def epoll_run(buf)
-    case kgio_tryread(HBUFSIZ, buf)
+    case kgio_tryread(CLIENT_HEADER_BUFFER_SIZE, buf)
     when :wait_readable
       return kato_set
     when String
@@ -105,7 +105,7 @@ module Rainbows::XEpollThreadSpawn::Client
 
   def pipeline_ready(hp)
     hp.parse and return true
-    case buf = kgio_tryread(HBUFSIZ)
+    case buf = kgio_tryread(CLIENT_HEADER_BUFFER_SIZE)
     when :wait_readable
       kato_set
       return false
diff --git a/t/client_header_buffer_size.ru b/t/client_header_buffer_size.ru
index 0831944..65cf793 100644
--- a/t/client_header_buffer_size.ru
+++ b/t/client_header_buffer_size.ru
@@ -1,3 +1,5 @@
 use Rack::ContentLength
 use Rack::ContentType, "text/plain"
-run lambda { |env| [ 200, {}, [ "#{Rainbows.client_header_buffer_size}\n" ] ] }
+run lambda { |env|
+  [ 200, {}, [ "#{Rainbows.server.client_header_buffer_size}\n" ] ]
+}