diff options
author | Eric Wong <e@80x24.org> | 2013-11-01 22:01:45 +0000 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2013-11-01 22:01:45 +0000 |
commit | 2260de380fc920f2d3108405ac3df5db7225a90e (patch) | |
tree | 2d4d9fd99a071ec5d273860f026db10588232b01 /lib | |
parent | 98b663091a919035ea85bc5273bfe4bd1aac2073 (diff) | |
download | yahns-2260de380fc920f2d3108405ac3df5db7225a90e.tar.gz |
This allows users to specify alternative temporary directories in case buffers get too large for one filesystem to handle or to give priority to some clients on certain ports.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/yahns/cap_input.rb | 4 | ||||
-rw-r--r-- | lib/yahns/config.rb | 23 | ||||
-rw-r--r-- | lib/yahns/http_context.rb | 20 | ||||
-rw-r--r-- | lib/yahns/http_response.rb | 4 | ||||
-rw-r--r-- | lib/yahns/tmpio.rb | 4 | ||||
-rw-r--r-- | lib/yahns/wbuf.rb | 4 |
6 files changed, 45 insertions, 14 deletions
diff --git a/lib/yahns/cap_input.rb b/lib/yahns/cap_input.rb index 1aa10b6..313b3ce 100644 --- a/lib/yahns/cap_input.rb +++ b/lib/yahns/cap_input.rb @@ -7,8 +7,8 @@ class Yahns::CapInput < Yahns::TmpIO # :nodoc: attr_writer :bytes_left - def self.new(limit) - rv = super() + def self.new(limit, tmpdir) + rv = super(tmpdir) rv.bytes_left = limit rv end diff --git a/lib/yahns/config.rb b/lib/yahns/config.rb index 1862eee..4ea51af 100644 --- a/lib/yahns/config.rb +++ b/lib/yahns/config.rb @@ -334,9 +334,7 @@ class Yahns::Config # :nodoc: end # boolean config directives for app - %w(check_client_connection - output_buffering - persistent_connections).each do |_v| + %w(check_client_connection persistent_connections).each do |_v| eval( %Q(def #{_v}(bool);) << %Q( _check_in_block(:app, :#{_v});) << @@ -345,6 +343,21 @@ class Yahns::Config # :nodoc: ) end + def output_buffering(bool, opts = {}) + var = _check_in_block(:app, :output_buffering) + @block.ctx.__send__("#{var}=", _check_bool(var, bool)) + tmpdir = opts[:tmpdir] and + @block.ctx.output_buffer_tmpdir = _check_tmpdir(var, tmpdir) + end + + def _check_tmpdir(var, path) + File.directory?(path) or + raise ArgumentError, "#{var} tmpdir: #{path} is not a directory" + File.writable?(path) or + raise ArgumentError, "#{var} tmpdir: #{path} is not writable" + path + end + # integer config directives for app { # config name, minimum value @@ -371,12 +384,14 @@ class Yahns::Config # :nodoc: @block.ctx.__send__("#{var}=", val) end - def input_buffering(val) + def input_buffering(val, opts = {}) var = _check_in_block(:app, :input_buffering) ok = [ :lazy, true, false ] ok.include?(val) or raise ArgumentError, "`#{var}' must be one of: #{ok.inspect}" @block.ctx.__send__("#{var}=", val) + tmpdir = opts[:tmpdir] and + @block.ctx.input_buffer_tmpdir = _check_tmpdir(var, tmpdir) end # used to configure rack.errors destination diff --git a/lib/yahns/http_context.rb b/lib/yahns/http_context.rb index 605989f..bd455bd 100644 --- a/lib/yahns/http_context.rb +++ b/lib/yahns/http_context.rb @@ -18,6 +18,8 @@ module Yahns::HttpContext # :nodoc: attr_accessor :queue # set right before spawning acceptors attr_reader :app attr_reader :app_defaults + attr_writer :input_buffer_tmpdir + attr_writer :output_buffer_tmpdir def http_ctx_init(yahns_rack) @yahns_rack = yahns_rack @@ -32,6 +34,10 @@ module Yahns::HttpContext # :nodoc: @client_timeout = 15 @qegg = nil @queue = nil + + # Dir.tmpdir can change while running, so leave these as nil + @input_buffer_tmpdir = nil + @output_buffer_tmpdir = nil end # call this after forking @@ -74,10 +80,20 @@ module Yahns::HttpContext # :nodoc: def tmpio_for(len) if len # Content-Length given - len <= @client_body_buffer_size ? StringIO.new("") : Yahns::TmpIO.new + len <= @client_body_buffer_size ? StringIO.new("") + : Yahns::TmpIO.new(input_buffer_tmpdir) else # chunked, unknown length mbs = @client_max_body_size - mbs ? Yahns::CapInput.new(mbs) : Yahns::TmpIO.new + tmpdir = input_buffer_tmpdir + mbs ? Yahns::CapInput.new(mbs, tmpdir) : Yahns::TmpIO.new(tmpdir) end end + + def input_buffer_tmpdir + @input_buffer_tmpdir || Dir.tmpdir + end + + def output_buffer_tmpdir + @output_buffer_tmpdir || Dir.tmpdir + end end diff --git a/lib/yahns/http_response.rb b/lib/yahns/http_response.rb index 6ddb1c8..f48b4d8 100644 --- a/lib/yahns/http_response.rb +++ b/lib/yahns/http_response.rb @@ -47,7 +47,7 @@ module Yahns::HttpResponse # :nodoc: alive = Yahns::StreamFile.new(body, alive, offset, count) body = nil end - wbuf = Yahns::Wbuf.new(body, alive) + wbuf = Yahns::Wbuf.new(body, alive, self.class.output_buffer_tmpdir) rv = wbuf.wbuf_write(self, header) body.each { |chunk| rv = wbuf.wbuf_write(self, chunk) } if body wbuf_maybe(wbuf, rv, alive) @@ -165,7 +165,7 @@ module Yahns::HttpResponse # :nodoc: chunk = rv # hope the skb grows when we loop into the trywrite when :wait_writable, :wait_readable if k.output_buffering - wbuf = Yahns::Wbuf.new(body, alive) + wbuf = Yahns::Wbuf.new(body, alive, k.output_buffer_tmpdir) rv = wbuf.wbuf_write(self, chunk) break else diff --git a/lib/yahns/tmpio.rb b/lib/yahns/tmpio.rb index 4fe4794..bcf6b8a 100644 --- a/lib/yahns/tmpio.rb +++ b/lib/yahns/tmpio.rb @@ -11,10 +11,10 @@ class Yahns::TmpIO < File # :nodoc: # creates and returns a new File object. The File is unlinked # immediately, switched to binary mode, and userspace output # buffering is disabled - def self.new + def self.new(tmpdir = Dir.tmpdir) retried = false begin - fp = super("#{Dir.tmpdir}/#{rand}", RDWR|CREAT|EXCL, 0600) + fp = super("#{tmpdir}/#{rand}", RDWR|CREAT|EXCL, 0600) rescue Errno::EEXIST retry rescue Errno::EMFILE, Errno::ENFILE diff --git a/lib/yahns/wbuf.rb b/lib/yahns/wbuf.rb index 8b2b82e..e6039b7 100644 --- a/lib/yahns/wbuf.rb +++ b/lib/yahns/wbuf.rb @@ -6,8 +6,8 @@ require_relative 'wbuf_common' class Yahns::Wbuf # :nodoc: include Yahns::WbufCommon - def initialize(body, persist) - @tmpio = Yahns::TmpIO.new + def initialize(body, persist, tmpdir) + @tmpio = Yahns::TmpIO.new(tmpdir) @sf_offset = @sf_count = 0 @wbuf_persist = persist # whether or not we keep the connection alive @body = body |