123456789_123456789_123456789_123456789_123456789_

Class: WEBrick::CGI

Relationships & Source Files
Inherits: Object
Defined in: lib/webrick/cgi.rb

Overview

A CGI library using ::WEBrick requests and responses.

Example:

class MyCGI < WEBrick::CGI
  def do_GET req, res
    res.body = 'it worked!'
    res.status = 200
  end
end

MyCGI.new.start

Constant Summary

Class Method Summary

Instance Attribute Summary

Instance Method Summary

Constructor Details

.new(*args) ⇒ CGI

Creates a new CGI interface.

The first argument in args is a configuration hash which would update Config::HTTP.

Any remaining arguments are stored in the @options instance variable for use by a subclass.

[ GitHub ]

  
# File 'lib/webrick/cgi.rb', line 55

def initialize(*args)
  if defined?(MOD_RUBY)
    unless ENV.has_key?("GATEWAY_INTERFACE")
      Apache.request.setup_cgi_env
    end
  end
  if %r{HTTP/(\d\.\d)} =~ ENV["SERVER_PROTOCOL"]
    httpv = $1
  end
  @config = WEBrick::Config::HTTP.dup.update(
    :ServerSoftware => ENV["SERVER_SOFTWARE"] || "null",
    :HTTPVersion    => HTTPVersion.new(httpv || "1.0"),
    :RunOnCGI       => true,   # to detect if it runs on CGI.
    :NPH            => false   # set true to run as NPH script.
  )
  if config = args.shift
    @config.update(config)
  end
  @config[:Logger] ||= WEBrick::BasicLog.new($stderr)
  @logger = @config[:Logger]
  @options = args
end

Instance Attribute Details

#config (readonly)

The CGI configuration. This is based on Config::HTTP

[ GitHub ]

  
# File 'lib/webrick/cgi.rb', line 39

attr_reader :config

#logger (readonly)

The CGI logger

[ GitHub ]

  
# File 'lib/webrick/cgi.rb', line 44

attr_reader :logger

Instance Method Details

#[](key)

Reads key from the configuration

[ GitHub ]

  
# File 'lib/webrick/cgi.rb', line 81

def [](key)
  @config[key]
end

#service(req, res)

Services the request req which will fill in the response res. See HTTPServlet::AbstractServlet#service for details.

[ GitHub ]

  
# File 'lib/webrick/cgi.rb', line 156

def service(req, res)
  method_name = "do_" + req.request_method.gsub(/-/, "_")
  if respond_to?(method_name)
    __send__(method_name, req, res)
  else
    raise HTTPStatus::MethodNotAllowed,
          "unsupported method `#{req.request_method}'."
  end
end

#start(env = ENV, stdin = $stdin, stdout = $stdout)

Starts the CGI process with the given environment env and standard input and output stdin and stdout.

[ GitHub ]

  
# File 'lib/webrick/cgi.rb', line 89

def start(env=ENV, stdin=$stdin, stdout=$stdout)
  sock = WEBrick::CGI::Socket.new(@config, env, stdin, stdout)
  req = HTTPRequest.new(@config)
  res = HTTPResponse.new(@config)
  unless @config[:NPH] or defined?(MOD_RUBY)
    def res.setup_header
      unless @header["status"]
        phrase = HTTPStatus::reason_phrase(@status)
        @header["status"] = "#{@status} #{phrase}"
      end
      super
    end
    def res.status_line
      ""
    end
  end

  begin
    req.parse(sock)
    req.script_name = (env["SCRIPT_NAME"] || File.expand_path($0)).dup
    req.path_info = (env["PATH_INFO"] || "").dup
    req.query_string = env["QUERY_STRING"]
    req.user = env["REMOTE_USER"]
    res.request_method = req.request_method
    res.request_uri = req.request_uri
    res.request_http_version = req.http_version
    res.keep_alive = req.keep_alive?
    self.service(req, res)
  rescue HTTPStatus::Error => ex
    res.set_error(ex)
  rescue HTTPStatus::Status => ex
    res.status = ex.code
  rescue Exception => ex
    @logger.error(ex)
    res.set_error(ex, true)
  ensure
    req.fixup
    if defined?(MOD_RUBY)
      res.setup_header
      Apache.request.status_line = "#{res.status} #{res.reason_phrase}"
      Apache.request.status = res.status
      table = Apache.request.headers_out
      res.header.each{|key, val|
        case key
        when /^content-encoding$/i
          Apache::request.content_encoding = val
        when /^content-type$/i
          Apache::request.content_type = val
        else
          table[key] = val.to_s
        end
      }
      res.cookies.each{|cookie|
        table.add("Set-Cookie", cookie.to_s)
      }
      Apache.request.send_http_header
      res.send_body(sock)
    else
      res.send_response(sock)
    end
  end
end