Class | WEBrick::HTTPServlet::CGIHandler |
In: |
lib/webrick/httpservlet/cgihandler.rb
|
Parent: | AbstractServlet |
Ruby | = | File::join(::Config::CONFIG['bindir'], ::Config::CONFIG['ruby_install_name']) |
CGIRunner | = | "\"#{Ruby}\" \"#{Config::LIBDIR}/httpservlet/cgi_runner.rb\"" |
# File lib/webrick/httpservlet/cgihandler.rb, line 25 25: def initialize(server, name) 26: super 27: @script_filename = name 28: @tempdir = server[:TempDir] 29: @cgicmd = "#{CGIRunner} #{server[:CGIInterpreter]}" 30: end
# File lib/webrick/httpservlet/cgihandler.rb, line 32 32: def do_GET(req, res) 33: data = nil 34: status = -1 35: 36: cgi_in = IO::popen(@cgicmd, "wb") 37: cgi_out = Tempfile.new("webrick.cgiout.", @tempdir) 38: cgi_err = Tempfile.new("webrick.cgierr.", @tempdir) 39: begin 40: cgi_in.sync = true 41: meta = req.meta_vars 42: meta["SCRIPT_FILENAME"] = @script_filename 43: meta["PATH"] = @config[:CGIPathEnv] 44: if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM 45: meta["SystemRoot"] = ENV["SystemRoot"] 46: end 47: dump = Marshal.dump(meta) 48: 49: cgi_in.write("%8d" % cgi_out.path.size) 50: cgi_in.write(cgi_out.path) 51: cgi_in.write("%8d" % cgi_err.path.size) 52: cgi_in.write(cgi_err.path) 53: cgi_in.write("%8d" % dump.size) 54: cgi_in.write(dump) 55: 56: if req.body and req.body.size > 0 57: cgi_in.write(req.body) 58: end 59: ensure 60: cgi_in.close 61: status = $?.exitstatus 62: sleep 0.1 if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM 63: data = cgi_out.read 64: cgi_out.close(true) 65: if errmsg = cgi_err.read 66: if errmsg.size > 0 67: @logger.error("CGIHandler: #{@script_filename}:\n" + errmsg) 68: end 69: end 70: cgi_err.close(true) 71: end 72: 73: if status != 0 74: @logger.error("CGIHandler: #{@script_filename} exit with #{status}") 75: end 76: 77: data = "" unless data 78: raw_header, body = data.split(/^[\xd\xa]+/on, 2) 79: raise HTTPStatus::InternalServerError, 80: "Premature end of script headers: #{@script_filename}" if body.nil? 81: 82: begin 83: header = HTTPUtils::parse_header(raw_header) 84: if /^(\d+)/ =~ header['status'][0] 85: res.status = $1.to_i 86: header.delete('status') 87: end 88: if header.has_key?('location') 89: # RFC 3875 6.2.3, 6.2.4 90: res.status = 302 unless (300...400) === res.status 91: end 92: if header.has_key?('set-cookie') 93: header['set-cookie'].each{|k| 94: res.cookies << Cookie.parse_set_cookie(k) 95: } 96: header.delete('set-cookie') 97: end 98: header.each{|key, val| res[key] = val.join(", ") } 99: rescue => ex 100: raise HTTPStatus::InternalServerError, ex.message 101: end 102: res.body = body 103: end