2009-03-05 22:56:38 -05:00
|
|
|
#
|
2003-07-23 12:51:36 -04:00
|
|
|
# cgihandler.rb -- CGIHandler Class
|
2009-03-05 22:56:38 -05:00
|
|
|
#
|
2003-07-23 12:51:36 -04:00
|
|
|
# Author: IPR -- Internet Programming with Ruby -- writers
|
|
|
|
# Copyright (c) 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
|
|
|
|
# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
|
|
|
|
# reserved.
|
2009-03-05 22:56:38 -05:00
|
|
|
#
|
2003-07-23 12:51:36 -04:00
|
|
|
# $IPR: cgihandler.rb,v 1.27 2003/03/21 19:56:01 gotoyuzo Exp $
|
|
|
|
|
|
|
|
require 'rbconfig'
|
|
|
|
require 'tempfile'
|
|
|
|
require 'webrick/config'
|
|
|
|
require 'webrick/httpservlet/abstract'
|
|
|
|
|
|
|
|
module WEBrick
|
|
|
|
module HTTPServlet
|
|
|
|
|
|
|
|
class CGIHandler < AbstractServlet
|
2009-12-31 10:00:04 -05:00
|
|
|
Ruby = RbConfig.ruby
|
2006-02-19 19:15:36 -05:00
|
|
|
CGIRunner = "\"#{Ruby}\" \"#{WEBrick::Config::LIBDIR}/httpservlet/cgi_runner.rb\""
|
2003-07-23 12:51:36 -04:00
|
|
|
|
|
|
|
def initialize(server, name)
|
2005-08-07 16:16:15 -04:00
|
|
|
super(server, name)
|
2003-07-23 12:51:36 -04:00
|
|
|
@script_filename = name
|
|
|
|
@tempdir = server[:TempDir]
|
|
|
|
@cgicmd = "#{CGIRunner} #{server[:CGIInterpreter]}"
|
|
|
|
end
|
|
|
|
|
|
|
|
def do_GET(req, res)
|
|
|
|
data = nil
|
|
|
|
status = -1
|
|
|
|
|
2003-09-23 13:14:39 -04:00
|
|
|
cgi_in = IO::popen(@cgicmd, "wb")
|
2010-03-12 03:48:10 -05:00
|
|
|
cgi_out = Tempfile.new("webrick.cgiout.", @tempdir, mode: IO::BINARY)
|
2008-01-07 06:40:41 -05:00
|
|
|
cgi_out.set_encoding("ASCII-8BIT")
|
2010-03-12 03:48:10 -05:00
|
|
|
cgi_err = Tempfile.new("webrick.cgierr.", @tempdir, mode: IO::BINARY)
|
2008-01-07 06:40:41 -05:00
|
|
|
cgi_err.set_encoding("ASCII-8BIT")
|
2003-07-23 12:51:36 -04:00
|
|
|
begin
|
|
|
|
cgi_in.sync = true
|
|
|
|
meta = req.meta_vars
|
|
|
|
meta["SCRIPT_FILENAME"] = @script_filename
|
|
|
|
meta["PATH"] = @config[:CGIPathEnv]
|
2004-07-18 11:59:02 -04:00
|
|
|
if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM
|
|
|
|
meta["SystemRoot"] = ENV["SystemRoot"]
|
|
|
|
end
|
2003-07-23 12:51:36 -04:00
|
|
|
dump = Marshal.dump(meta)
|
|
|
|
|
2008-11-08 04:41:24 -05:00
|
|
|
cgi_in.write("%8d" % cgi_out.path.bytesize)
|
2003-07-23 12:51:36 -04:00
|
|
|
cgi_in.write(cgi_out.path)
|
2008-11-08 04:41:24 -05:00
|
|
|
cgi_in.write("%8d" % cgi_err.path.bytesize)
|
2003-07-23 12:51:36 -04:00
|
|
|
cgi_in.write(cgi_err.path)
|
2008-11-08 04:41:24 -05:00
|
|
|
cgi_in.write("%8d" % dump.bytesize)
|
2003-07-23 12:51:36 -04:00
|
|
|
cgi_in.write(dump)
|
|
|
|
|
2008-11-08 04:41:24 -05:00
|
|
|
if req.body and req.body.bytesize > 0
|
2003-07-23 12:51:36 -04:00
|
|
|
cgi_in.write(req.body)
|
|
|
|
end
|
|
|
|
ensure
|
|
|
|
cgi_in.close
|
2004-03-07 11:06:43 -05:00
|
|
|
status = $?.exitstatus
|
2004-07-18 11:59:02 -04:00
|
|
|
sleep 0.1 if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM
|
2003-07-23 12:51:36 -04:00
|
|
|
data = cgi_out.read
|
|
|
|
cgi_out.close(true)
|
|
|
|
if errmsg = cgi_err.read
|
2008-11-08 04:41:24 -05:00
|
|
|
if errmsg.bytesize > 0
|
2003-07-23 12:51:36 -04:00
|
|
|
@logger.error("CGIHandler: #{@script_filename}:\n" + errmsg)
|
|
|
|
end
|
2009-03-05 22:56:38 -05:00
|
|
|
end
|
2003-07-23 12:51:36 -04:00
|
|
|
cgi_err.close(true)
|
|
|
|
end
|
2009-03-05 22:56:38 -05:00
|
|
|
|
2003-07-23 12:51:36 -04:00
|
|
|
if status != 0
|
|
|
|
@logger.error("CGIHandler: #{@script_filename} exit with #{status}")
|
|
|
|
end
|
|
|
|
|
|
|
|
data = "" unless data
|
2009-03-05 22:56:38 -05:00
|
|
|
raw_header, body = data.split(/^[\xd\xa]+/, 2)
|
2003-07-23 12:51:36 -04:00
|
|
|
raise HTTPStatus::InternalServerError,
|
2004-03-07 11:06:43 -05:00
|
|
|
"Premature end of script headers: #{@script_filename}" if body.nil?
|
2003-07-23 12:51:36 -04:00
|
|
|
|
|
|
|
begin
|
|
|
|
header = HTTPUtils::parse_header(raw_header)
|
|
|
|
if /^(\d+)/ =~ header['status'][0]
|
|
|
|
res.status = $1.to_i
|
|
|
|
header.delete('status')
|
|
|
|
end
|
2008-05-28 03:13:04 -04:00
|
|
|
if header.has_key?('location')
|
|
|
|
# RFC 3875 6.2.3, 6.2.4
|
|
|
|
res.status = 302 unless (300...400) === res.status
|
|
|
|
end
|
2005-10-30 15:40:05 -05:00
|
|
|
if header.has_key?('set-cookie')
|
|
|
|
header['set-cookie'].each{|k|
|
|
|
|
res.cookies << Cookie.parse_set_cookie(k)
|
|
|
|
}
|
|
|
|
header.delete('set-cookie')
|
|
|
|
end
|
2003-07-23 12:51:36 -04:00
|
|
|
header.each{|key, val| res[key] = val.join(", ") }
|
|
|
|
rescue => ex
|
|
|
|
raise HTTPStatus::InternalServerError, ex.message
|
|
|
|
end
|
|
|
|
res.body = body
|
|
|
|
end
|
|
|
|
alias do_POST do_GET
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|