diff options
author | Eric Wong <e@80x24.org> | 2018-12-26 19:57:13 +0000 |
---|---|---|
committer | Eric Wong <e@80x24.org> | 2018-12-27 05:59:37 +0000 |
commit | 5424d873608d24d4665ff5f44c7fabaafc69eaa0 (patch) | |
tree | ff2f217a8369794023cdddb758d75a3a008578b4 | |
parent | cd9058ec72ffac6d5dc0d6ed253c9c984c6906e4 (diff) | |
download | yahns-5424d873608d24d4665ff5f44c7fabaafc69eaa0.tar.gz |
We don't need non-blocking I/O at all in this module and it's not coupled with the rest of yahns at all.
-rw-r--r-- | extras/exec_cgi.rb | 46 |
1 files changed, 30 insertions, 16 deletions
diff --git a/extras/exec_cgi.rb b/extras/exec_cgi.rb index b546e1f..7fb5138 100644 --- a/extras/exec_cgi.rb +++ b/extras/exec_cgi.rb @@ -21,18 +21,29 @@ # run ExecCgi.new('/path/to/cgit.cgi') # cgit: https://git.zx2c4.com/cgit/ # class ExecCgi - class MyIO < Kgio::Pipe + class MyIO attr_writer :my_pid attr_writer :body_tip + attr_reader :rd + + def initialize(rd) + @rd = rd + end def each buf = @body_tip || ''.dup if buf.size > 0 yield buf end - while tmp = kgio_read(8192, buf) + + case tmp = @rd.read_nonblock(8192, buf, exception: false) + when :wait_readable + @rd.wait_readable + when nil + break + else # String yield tmp - end + end while true self ensure # do this sooner, since the response body may be buffered, we want @@ -46,8 +57,8 @@ class ExecCgi # Note: this object (and any client-specific objects) will never # be shared across different threads, so we do not need extra # mutual exclusion here. - return if closed? - super + return if @rd.closed? + @rd.close begin Process.waitpid(@my_pid) rescue Errno::ECHILD @@ -90,20 +101,23 @@ class ExecCgi cgi_env = { "GATEWAY_INTERFACE" => "CGI/1.1" } PASS_VARS.each { |key| val = env[key] and cgi_env[key] = val } env.each { |key,val| cgi_env[key] = val if key =~ /\AHTTP_/ } - pipe = MyIO.pipe - errbody = pipe[0] - errbody.my_pid = Process.spawn(cgi_env.merge!(@env), *@args, - out: pipe[1], close_others: true) - pipe[1].close - pipe = pipe[0] - if head = pipe.kgio_read(8192) + rd, wr = IO.pipe + io = MyIO.new(rd) + errbody = io + errbody.my_pid = spawn(cgi_env.merge!(@env), *@args, + out: wr, close_others: true) + wr.close + + begin + head = rd.readpartial(8192) until head =~ /\r?\n\r?\n/ - tmp = pipe.kgio_read(8192) or break + tmp = rd.readpartial(8192) head << tmp + tmp.clear end head, body = head.split(/\r?\n\r?\n/, 2) - pipe.body_tip = body + io.body_tip = body env["HTTP_VERSION"] ||= "HTTP/1.0" # stop Rack::Chunked for HTTP/0.9 @@ -117,8 +131,8 @@ class ExecCgi end status = headers.delete("Status") || 200 errbody = nil - [ status, headers, pipe ] - else + [ status, headers, io ] + rescue EOFError [ 500, { "Content-Length" => "0", "Content-Type" => "text/plain" }, [] ] end ensure |