| 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