# Web::Interface::CGI
# Copyright(c) 2002-2004 MoonWolf <moonwolf@moonwolf.com>
require 'web/interface/basic'

module Web
  module Interface
    class CGI < Basic
      EOL = "\r\n"
      def initialize(opt={})
        @opt       = opt
        @input     = opt[:stdin]   || $stdin
        @output    = opt[:stdout]  || $stdout
        @env       = opt[:env]     || ENV
        #@persisent = opt[:storage] || Web::Persistent::File
        @eof       = false
      end
      
      # 標準入力からRequestを組み立てる
      def request(arg={})
        return nil if @eof
        @eof = true
        super
        req = Web::Request.new
        #
        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']
        
        # 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 # CGI#request
      
      def response(req, rsp)
        super
        out = @output
        # ヘッダ出力
        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|
          out << 'Set-Cookie: ' << cookie.to_response_header << EOL
        }
        out << EOL
        
        #
        out << rsp.body
        req.cleanup
      end # CGI#response
    end # CGI
  end # Interface
end # Web
