In Files

  • cgi/cookie.rb
  • cgi/core.rb
  • cgi/html.rb
  • cgi/session.rb
  • cgi/session/pstore.rb
  • cgi/util.rb

CGI

Class representing an HTTP cookie.

In addition to its specific fields and methods, a Cookie instance is a delegator to the array of its values.

See RFC 2965.

Examples of use

cookie1 = CGI::Cookie::new("name", "value1", "value2", ...)
cookie1 = CGI::Cookie::new("name" => "name", "value" => "value")
cookie1 = CGI::Cookie::new('name'    => 'name',
                           'value'   => ['value1', 'value2', ...],
                           'path'    => 'path',   # optional
                           'domain'  => 'domain', # optional
                           'expires' => Time.now, # optional
                           'secure'  => true      # optional
                          )

cgi.out("cookie" => [cookie1, cookie2]) { "string" }

name    = cookie1.name
values  = cookie1.value
path    = cookie1.path
domain  = cookie1.domain
expires = cookie1.expires
secure  = cookie1.secure

cookie1.name    = 'name'
cookie1.value   = ['value1', 'value2', ...]
cookie1.path    = 'path'
cookie1.domain  = 'domain'
cookie1.expires = Time.now + 30
cookie1.secure  = true

Provides methods for code generation for tags following the various DTD element types.

Constants

CR

String for carriage return

EOL

Standard internet newline sequence

HTTP_STATUS

HTTP status codes.

LF

String for linefeed

MAX_MULTIPART_COUNT

Maximum number of request parameters when multipart

MAX_MULTIPART_LENGTH

Maximum content length of multipart data

NEEDS_BINMODE
PATH_SEPARATOR

Path separators in different environments.

RFC822_DAYS

Abbreviated day-of-week names specified by RFC 822

RFC822_MONTHS

Abbreviated month names specified by RFC 822

TABLE_FOR_ESCAPE_HTML__

Attributes

accept_charset[R]

Create a new CGI instance.

CGI accept constructor parameters either in a hash, string as a block. But string is as same as using :tag_maker of hash.

CGI.new("html3") #=>  CGI.new(:tag_maker=>"html3")

And, if you specify string, @accept_charset cannot be changed. Instead, please use hash parameter.

::accept_charset

:accept_charset specifies encoding of received query string. ( Default value is @@accept_charset. ) If not valid, raise CGI::InvalidEncoding

Example. Suppose @@accept_charset # => “UTF-8”

when not specified:

cgi=CGI.new      # @accept_charset # => "UTF-8"

when specified “EUC-JP”:

cgi=CGI.new(:accept_charset => "EUC-JP") # => "EUC-JP"

block

When you use a block, you can write a process that query encoding is invalid. Example:

encoding_error={}
cgi=CGI.new(:accept_charset=>"EUC-JP") do |name,value| 
  encoding_error[key] = value
end

tag_maker

:tag_maker specifies which version of HTML to load the HTML generation methods for. The following versions of HTML are supported:

html3

HTML 3.x

html4

HTML 4.0

html4Tr

HTML 4.0 Transitional

html4Fr

HTML 4.0 with Framesets

If not specified, no HTML generation methods will be loaded.

If the CGI object is not created in a standard CGI call environment (that is, it can't locate REQUEST_METHOD in its environment), then it will run in “offline” mode. In this mode, it reads its parameters from the command line or (failing that) from standard input. Otherwise, cookies and other parameters are parsed automatically from the standard CGI locations, which varies according to the REQUEST_METHOD. It works this:

CGI.new(:tag_maker=>"html3")

This will be obsolete:

CGI.new("html3")

Public Class Methods

accept_charset() click to toggle source
 
               # File cgi/core.rb, line 667
def self.accept_charset
  @@accept_charset
end
            
accept_charset=(accept_charset) click to toggle source
 
               # File cgi/core.rb, line 671
def self.accept_charset=(accept_charset)
  @@accept_charset=accept_charset
end
            
escape(string) click to toggle source

URL-encode a string.

url_encoded_string = CGI::escape("'Stop!' said Fred")
   # => "%27Stop%21%27+said+Fred"
 
               # File cgi/util.rb, line 5
def CGI::escape(string)
  string.gsub(/([^ a-zA-Z0-9_.-]+)/) do
    '%' + $1.unpack('H2' * $1.bytesize).join('%').upcase
  end.tr(' ', '+')
end
            
escapeElement(string, *elements) click to toggle source

Escape only the tags of certain HTML elements in string.

Takes an element or elements or array of elements. Each element is specified by the name of the element, without angle brackets. This matches both the start and the end tag of that element. The attribute list of the open tag will also be escaped (for instance, the double-quotes surrounding attribute values).

print CGI::escapeElement('<BR><A HREF="url"></A>', "A", "IMG")
  # "<BR>&lt;A HREF=&quot;url&quot;&gt;&lt;/A&gt"

print CGI::escapeElement('<BR><A HREF="url"></A>', ["A", "IMG"])
  # "<BR>&lt;A HREF=&quot;url&quot;&gt;&lt;/A&gt"
 
               # File cgi/util.rb, line 105
def CGI::escapeElement(string, *elements)
  elements = elements[0] if elements[0].kind_of?(Array)
  unless elements.empty?
    string.gsub(/<\/?(?:#{elements.join("|")})(?!\w)(?:.|\n)*?>/i) do
      CGI::escapeHTML($&)
    end
  else
    string
  end
end
            
escapeHTML(string) click to toggle source

Escape special characters in HTML, namely &"<>

CGI::escapeHTML('Usage: foo "bar" <baz>')
   # => "Usage: foo &quot;bar&quot; &lt;baz&gt;"
 
               # File cgi/util.rb, line 32
def CGI::escapeHTML(string)
  string.gsub(/[&\"<>]/, TABLE_FOR_ESCAPE_HTML__)
end
            
escape_element(str) click to toggle source
 
               # File cgi/util.rb, line 136
def CGI::escape_element(str)
  escapeElement(str)
end
            
escape_html(str) click to toggle source
 
               # File cgi/util.rb, line 85
def CGI::escape_html(str)
  escapeHTML(str)
end
            
new(options = {},&block) click to toggle source
 
               # File cgi/core.rb, line 737
def initialize(options = {},&block)
  @accept_charset_error_block=block if block_given?
  @options={:accept_charset=>@@accept_charset}
  case options
  when Hash
    @options.merge!(options)
  when String
    @options[:tag_maker]=options
  end
  @accept_charset=@options[:accept_charset]
  if defined?(MOD_RUBY) && !ENV.key?("GATEWAY_INTERFACE")
    Apache.request.setup_cgi_env
  end

  extend QueryExtension
  @multipart = false

  initialize_query()  # set @params, @cookies
  @output_cookies = nil
  @output_hidden = nil

  case @options[:tag_maker]
  when "html3"
    require 'cgi/html'
    extend Html3
    element_init()
    extend HtmlExtension
  when "html4"
    require 'cgi/html'
    extend Html4
    element_init()
    extend HtmlExtension
  when "html4Tr"
    require 'cgi/html'
    extend Html4Tr
    element_init()
    extend HtmlExtension
  when "html4Fr"
    require 'cgi/html'
    extend Html4Tr
    element_init()
    extend Html4Fr
    element_init()
    extend HtmlExtension
  end
end
            
parse(query) click to toggle source

Parse an HTTP query string into a hash of key=>value pairs.

params = CGI::parse("query_string")
  # {"name1" => ["value1", "value2", ...],
  #  "name2" => ["value1", "value2", ...], ... }
 
               # File cgi/core.rb, line 336
def CGI::parse(query)
  params = {}
  query.split(/[&;]/).each do |pairs|
    key, value = pairs.split('=',2).collect{|v| CGI::unescape(v) }
    if key && value
      params.has_key?(key) ? params[key].push(value) : params[key] = [value]
    elsif key
      params[key]=[]
    end
  end
  params.default=[].freeze
  params
end
            
pretty(string, shift = " ") click to toggle source

Prettify (indent) an HTML string.

string is the HTML string to indent. shift is the indentation unit to use; it defaults to two spaces.

print CGI::pretty("<HTML><BODY></BODY></HTML>")
  # <HTML>
  #   <BODY>
  #   </BODY>
  # </HTML>

print CGI::pretty("<HTML><BODY></BODY></HTML>", "\t")
  # <HTML>
  #         <BODY>
  #         </BODY>
  # </HTML>
 
               # File cgi/util.rb, line 171
def CGI::pretty(string, shift = "  ")
  lines = string.gsub(/(?!\A)<(?:.|\n)*?>/, "\n\\0").gsub(/<(?:.|\n)*?>(?!\n)/, "\\0\n")
  end_pos = 0
  while end_pos = lines.index(/^<\/(\w+)/, end_pos)
    element = $1.dup
    start_pos = lines.rindex(/^\s*<#{element}/i, end_pos)
    lines[start_pos ... end_pos] = "__" + lines[start_pos ... end_pos].gsub(/\n(?!\z)/, "\n" + shift) + "__"
  end
  lines.gsub(/^((?:#{Regexp::quote(shift)})*)__(?=<\/?\w)/, '\1')
end
            
rfc1123_date(time) click to toggle source

Format a Time object as a String using the format specified by RFC 1123.

CGI::rfc1123_date(Time.now)
  # Sat, 01 Jan 2000 00:00:00 GMT
 
               # File cgi/util.rb, line 147
def CGI::rfc1123_date(time)
  t = time.clone.gmtime
  return format("%s, %.2d %s %.4d %.2d:%.2d:%.2d GMT",
              RFC822_DAYS[t.wday], t.day, RFC822_MONTHS[t.month-1], t.year,
              t.hour, t.min, t.sec)
end
            
unescape(string) click to toggle source

URL-decode a string.

string = CGI::unescape("%27Stop%21%27+said+Fred")
   # => "'Stop!' said Fred"
 
               # File cgi/util.rb, line 15
def CGI::unescape(string)
  enc = string.encoding
  string.tr('+', ' ').gsub(/((?:%[0-9a-fA-F]{2})+)/) do
    [$1.delete('%')].pack('H*').force_encoding(enc)
  end
end
            
unescapeElement(string, *elements) click to toggle source

Undo escaping such as that done by ::escapeElement

print CGI::unescapeElement(
        CGI::escapeHTML('<BR><A HREF="url"></A>'), "A", "IMG")
  # "&lt;BR&gt;<A HREF="url"></A>"

print CGI::unescapeElement(
        CGI::escapeHTML('<BR><A HREF="url"></A>'), ["A", "IMG"])
  # "&lt;BR&gt;<A HREF="url"></A>"
 
               # File cgi/util.rb, line 126
def CGI::unescapeElement(string, *elements)
  elements = elements[0] if elements[0].kind_of?(Array)
  unless elements.empty?
    string.gsub(/&lt;\/?(?:#{elements.join("|")})(?!\w)(?:.|\n)*?&gt;/i) do
      CGI::unescapeHTML($&)
    end
  else
    string
  end
end
            
unescapeHTML(string) click to toggle source

Unescape a string that has been HTML-escaped

CGI::unescapeHTML("Usage: foo &quot;bar&quot; &lt;baz&gt;")
   # => "Usage: foo \"bar\" <baz>"
 
               # File cgi/util.rb, line 40
def CGI::unescapeHTML(string)
  enc = string.encoding
  if [Encoding::UTF_16BE, Encoding::UTF_16LE, Encoding::UTF_32BE, Encoding::UTF_32LE].include?(enc)
    return string.gsub(Regexp.new('&(amp|quot|gt|lt|#[0-9]+|#x[0-9A-Fa-f]+);'.encode(enc))) do
      case $1.encode("US-ASCII")
      when 'amp'                 then '&'.encode(enc)
      when 'quot'                then '"'.encode(enc)
      when 'gt'                  then '>'.encode(enc)
      when 'lt'                  then '<'.encode(enc)
      when /\A#0*(\d+)\z/        then $1.to_i.chr(enc)
      when /\A#x([0-9a-f]+)\z/i  then $1.hex.chr(enc)
      end
    end
  end
  asciicompat = Encoding.compatible?(string, "a")
  string.gsub(/&(amp|quot|gt|lt|\#[0-9]+|\#x[0-9A-Fa-f]+);/) do
    match = $1.dup
    case match
    when 'amp'                 then '&'
    when 'quot'                then '"'
    when 'gt'                  then '>'
    when 'lt'                  then '<'
    when /\A#0*(\d+)\z/
      n = $1.to_i
      if enc == Encoding::UTF_8 or
        enc == Encoding::ISO_8859_1 && n < 256 or
        asciicompat && n < 128
        n.chr(enc)
      else
        "&##{$1};"
      end
    when /\A#x([0-9a-f]+)\z/i
      n = $1.hex
      if enc == Encoding::UTF_8 or
        enc == Encoding::ISO_8859_1 && n < 256 or
        asciicompat && n < 128
        n.chr(enc)
      else
        "&#x#{$1};"
      end
    else
      "&#{match};"
    end
  end
end
            
unescape_element(str) click to toggle source
 
               # File cgi/util.rb, line 139
def CGI::unescape_element(str)
  unescapeElement(str)
end
            
unescape_html(str) click to toggle source
 
               # File cgi/util.rb, line 88
def CGI::unescape_html(str)
  unescapeHTML(str)
end
            

Public Instance Methods

header(options='text/html') click to toggle source

Create an HTTP header block as a string.

Includes the empty line that ends the header block.

options can be a string specifying the Content-Type (defaults to text/html), or a hash of header key/value pairs. The following header keys are recognized:

type

the Content-Type header. Defaults to “text/html”

charset

the charset of the body, appended to the Content-Type header.

nph

a boolean value. If true, prepend protocol string and status code, and date; and sets default values for “server” and “connection” if not explicitly set.

status

the HTTP status code, returned as the Status header. See the list of available status codes below.

server

the server software, returned as the Server header.

connection

the connection type, returned as the Connection header (for instance, “close”.

length

the length of the content that will be sent, returned as the Content-Length header.

language

the language of the content, returned as the Content-Language header.

expires

the time on which the current content expires, as a Time object, returned as the Expires header.

cookie

a cookie or cookies, returned as one or more Set-Cookie headers. The value can be the literal string of the cookie; a CGI::Cookie object; an Array of literal cookie strings or Cookie objects; or a hash all of whose values are literal cookie strings or Cookie objects. These cookies are in addition to the cookies held in the @output_cookies field.

Other header lines can also be set; they are appended as key: value.

header
  # Content-Type: text/html

header("text/plain")
  # Content-Type: text/plain

header("nph"        => true,
       "status"     => "OK",  # == "200 OK"
         # "status"     => "200 GOOD",
       "server"     => ENV['SERVER_SOFTWARE'],
       "connection" => "close",
       "type"       => "text/html",
       "charset"    => "iso-2022-jp",
         # Content-Type: text/html; charset=iso-2022-jp
       "length"     => 103,
       "language"   => "ja",
       "expires"    => Time.now + 30,
       "cookie"     => [cookie1, cookie2],
       "my_header1" => "my_value"
       "my_header2" => "my_value")

The status codes are:

"OK"                  --> "200 OK"
"PARTIAL_CONTENT"     --> "206 Partial Content"
"MULTIPLE_CHOICES"    --> "300 Multiple Choices"
"MOVED"               --> "301 Moved Permanently"
"REDIRECT"            --> "302 Found"
"NOT_MODIFIED"        --> "304 Not Modified"
"BAD_REQUEST"         --> "400 Bad Request"
"AUTH_REQUIRED"       --> "401 Authorization Required"
"FORBIDDEN"           --> "403 Forbidden"
"NOT_FOUND"           --> "404 Not Found"
"METHOD_NOT_ALLOWED"  --> "405 Method Not Allowed"
"NOT_ACCEPTABLE"      --> "406 Not Acceptable"
"LENGTH_REQUIRED"     --> "411 Length Required"
"PRECONDITION_FAILED" --> "412 Precondition Failed"
"SERVER_ERROR"        --> "500 Internal Server Error"
"NOT_IMPLEMENTED"     --> "501 Method Not Implemented"
"BAD_GATEWAY"         --> "502 Bad Gateway"
"VARIANT_ALSO_VARIES" --> "506 Variant Also Negotiates"

This method does not perform charset conversion.

 
               # File cgi/core.rb, line 142
def header(options='text/html')
  if options.is_a?(String)
    content_type = options
    buf = _header_for_string(content_type)
  elsif options.is_a?(Hash)
    if options.size == 1 && options.has_key?('type')
      content_type = options['type']
      buf = _header_for_string(content_type)
    else
      buf = _header_for_hash(options.dup)
    end
  else
    raise ArgumentError.new("expected String or Hash but got #{options.class}")
  end
  if defined?(MOD_RUBY)
    _header_for_modruby(buf)
    return ''
  else
    buf << EOL    # empty line of separator
    return buf
  end
end
            
out(options = "text/html") click to toggle source

Print an HTTP header and body to $DEFAULT_OUTPUT ($>)

The header is provided by options, as for header(). The body of the document is that returned by the passed- in block. This block takes no arguments. It is required.

cgi = CGI.new
cgi.out{ "string" }
  # Content-Type: text/html
  # Content-Length: 6
  #
  # string

cgi.out("text/plain") { "string" }
  # Content-Type: text/plain
  # Content-Length: 6
  #
  # string

cgi.out("nph"        => true,
        "status"     => "OK",  # == "200 OK"
        "server"     => ENV['SERVER_SOFTWARE'],
        "connection" => "close",
        "type"       => "text/html",
        "charset"    => "iso-2022-jp",
          # Content-Type: text/html; charset=iso-2022-jp
        "language"   => "ja",
        "expires"    => Time.now + (3600 * 24 * 30),
        "cookie"     => [cookie1, cookie2],
        "my_header1" => "my_value",
        "my_header2" => "my_value") { "string" }

Content-Length is automatically calculated from the size of the String returned by the content block.

If ENV == “HEAD”, then only the header is outputted (the content block is still required, but it is ignored).

If the charset is “iso-2022-jp” or “euc-jp” or “shift_jis” then the content is converted to this charset, and the language is set to “ja”.

 
               # File cgi/core.rb, line 310
def out(options = "text/html") # :yield:

  options = { "type" => options } if options.kind_of?(String)
  content = yield
  options["length"] = content.bytesize.to_s
  output = stdoutput
  output.binmode if defined? output.binmode
  output.print header(options)
  output.print content unless "HEAD" == env_table['REQUEST_METHOD']
end