21: def self.dispatch_cgi(app, cgi, out = $stdout)
22: env = cgi.__send__(:env_table)
23: env.delete "HTTP_CONTENT_LENGTH"
24:
25: cgi.stdinput.extend ProperStream
26:
27: env["SCRIPT_NAME"] = "" if env["SCRIPT_NAME"] == "/"
28:
29: env.update({
30: "rack.version" => [0,1],
31: "rack.input" => cgi.stdinput,
32: "rack.errors" => $stderr,
33: "rack.multithread" => false,
34: "rack.multiprocess" => true,
35: "rack.run_once" => false,
36: "rack.url_scheme" => ["yes", "on", "1"].include?(env["HTTPS"]) ? "https" : "http"
37: })
38:
39: env["QUERY_STRING"] ||= ""
40: env["HTTP_VERSION"] ||= env["SERVER_PROTOCOL"]
41: env["REQUEST_PATH"] ||= "/"
42: env.delete "PATH_INFO" if env["PATH_INFO"] == ""
43:
44: status, headers, body = app.call(env)
45: begin
46: out.binmode if out.respond_to?(:binmode)
47: out.sync = false if out.respond_to?(:sync=)
48:
49: headers['Status'] = status.to_s
50:
51: if headers.include?('Set-Cookie')
52: headers['cookie'] = headers.delete('Set-Cookie').split("\n")
53: end
54:
55: out.write(cgi.header(headers))
56:
57: body.each { |part|
58: out.write part
59: out.flush if out.respond_to?(:flush)
60: }
61: ensure
62: body.close if body.respond_to?(:close)
63: end
64: end