Re-enable spec/library for full CI runs.
[rbx.git] / lib / webrick / httpservlet / cgihandler.rb
bloba35b59edb8b0cf350d01a5458ffc7a97b4dce48a
1
2 # cgihandler.rb -- CGIHandler Class
3 #       
4 # Author: IPR -- Internet Programming with Ruby -- writers
5 # Copyright (c) 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
6 # Copyright (c) 2002 Internet Programming with Ruby writers. All rights
7 # reserved.
8 #   
9 # $IPR: cgihandler.rb,v 1.27 2003/03/21 19:56:01 gotoyuzo Exp $
11 require 'rbconfig'
12 require 'tempfile'
13 require 'webrick/config'
14 require 'webrick/httpservlet/abstract'
16 module WEBrick
17   module HTTPServlet
19     class CGIHandler < AbstractServlet
20       Ruby = File::join(::Config::CONFIG['bindir'],
21                         ::Config::CONFIG['ruby_install_name'])
22       Ruby << ::Config::CONFIG['EXEEXT']
23       CGIRunner = "\"#{Ruby}\" \"#{Config::LIBDIR}/httpservlet/cgi_runner.rb\""
25       def initialize(server, name)
26         super
27         @script_filename = name
28         @tempdir = server[:TempDir]
29         @cgicmd = "#{CGIRunner} #{server[:CGIInterpreter]}"
30       end
32       def do_GET(req, res)
33         data = nil
34         status = -1
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)
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)
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
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?
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?('set-cookie')
89             header['set-cookie'].each{|k|
90               res.cookies << Cookie.parse_set_cookie(k)
91             }
92             header.delete('set-cookie')
93           end
94           header.each{|key, val| res[key] = val.join(", ") }
95         rescue => ex
96           raise HTTPStatus::InternalServerError, ex.message
97         end
98         res.body = body
99       end
100       alias do_POST do_GET
101     end
103   end