# Web::Interface::FastCGI # Copyright(c) 2002 MoonWolf require 'web/interface/basic' module Web module Interface class FastCGI < Basic EOL = "\r\n" def initialize(opt={}) require "fcgi" @sigterm = false trap('SIGTERM') { @sigterm = true } end # 標準入力からRequestを組み立てる def request(arg={}) super req = Web::Request.new r = FCGI.accept return nil if @sigterm return nil unless r env = r.env input = r.in output = r.out req.env['fcgi_request'] = r # req.request_id = env['UNIQUE_ID'] || Web::Common::unique_id req.method = env['REQUEST_METHOD'] || 'GET' req.query_string = env['QUERY_STRING'] || '' req.script_name = env['SCRIPT_NAME'] req.path_info = env['PATH_INFO'] req.path_translated = env['PATH_TRANSLATED'] req.server_name = env['SERVER_NAME'] req.server_port = env['SERVER_PORT'] req.server_protocol = env['SERVER_PROTOCOL'] req.host = env['HTTP_HOST'] req.remote_addr = env['REMOTE_ADDR'] || '' req.remote_host = env['REMOTE_HOST'] || req.remote_addr req.auth_type = env['AUTH_TYPE'] || '' req.remote_ident = env['REMOTE_IDENT'] || '' req.remote_user = env['REMOTE_USER'] req.https = env['HTTPS'] ? true : false # header if len = env['CONTENT_LENGTH'] req.header['CONTENT-LENGTH'] = len end type = env['CONTENT_TYPE'] req.header['CONTENT-TYPE'] = type if type env.each {|key,value| if key=~/^HTTP_([0-9a-zA-Z_]+)/ field = $1.upcase.tr("_","-") req.header[field] = value end } # cookie if cookie = req.header['COOKIE'] req.cookies.parse(cookie, req) end ## param # QUERY_STRING parse_query(req.query_string || '', req.query) ## body case req.method when 'GET' # body req.body = nil when 'POST' ## form case req.header['CONTENT-TYPE'] when /^multipart\/form-data\s*;\s*boundary="?(.*)"?/ boundary=$1 parse_multipart(input, boundary, req.form) when /^application\/x-www-form-urlencoded/ parse_query(input.read.to_s, req.form) else req.body = input.read end end get_session_id req req end # FastCGI#request def response(req, rsp) exit if @sigterm super begin r = req.env['fcgi_request'] out = r.out # ヘッダ出力 out << 'Status: ' << rsp.status << EOL rsp.header.each {|key,value| field = key.split('-').collect! {|i| i.capitalize }.join('-') << ': ' value.each {|v| out << (field + v + EOL) } } rsp.cookies.each {|key,cookie_ary| cookie_ary.each {|cookie| out << 'Set-Cookie: ' << cookie.to_response_header << EOL } } out << EOL # out << rsp.body req.cleanup r.finish rescue Errno::EPIPE end end # FastCGI#response end # FastCGI end # Interface end # Web