Object
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.
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
Base module for HTML-generation mixins.
Provides methods for code generation for tags following the various DTD element types.
String for carriage return
Standard internet newline sequence
HTTP status codes.
String for linefeed
Maximum number of request parameters when multipart
Maximum content length of multipart data
Path separators in different environments.
Abbreviated day-of-week names specified by RFC 822
Abbreviated month names specified by RFC 822
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 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"
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 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")
# File cgi/core.rb, line 672
def self.accept_charset
@@accept_charset
end
# File cgi/core.rb, line 676
def self.accept_charset=(accept_charset)
@@accept_charset=accept_charset
end
URL-encode a string.
url_encoded_string = CGI::escape("'Stop!' said Fred") # => "%27Stop%21%27+said+Fred"
# File cgi/util.rb, line 6
def CGI::escape(string)
string.gsub(/([^ a-zA-Z0-9_.-]+)/) do
'%' + $1.unpack('H2' * $1.bytesize).join('%').upcase
end.tr(' ', '+')
end
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><A HREF="url"></A>" print CGI::escapeElement('<BR><A HREF="url"></A>', ["A", "IMG"]) # "<BR><A HREF="url"></A>"
# File cgi/util.rb, line 106
def CGI::escapeElement(string, *elements)
elements = elements[0] if elements[0].kind_of?(Array)
unless elements.empty?
string.gsub(/<\/?(?:#{elements.join("|")})(?!\w)(?:.|\n)*?>/) do
CGI::escapeHTML($&)
end
else
string
end
end
Escape special characters in HTML, namely &"<>
CGI::escapeHTML('Usage: foo "bar" <baz>') # => "Usage: foo "bar" <baz>"
# File cgi/util.rb, line 33
def CGI::escapeHTML(string)
string.gsub(/[&\"<>]/, TABLE_FOR_ESCAPE_HTML__)
end
# File cgi/util.rb, line 137
def CGI::escape_element(str)
escapeElement(str)
end
# File cgi/util.rb, line 86
def CGI::escape_html(str)
escapeHTML(str)
end
# File cgi/core.rb, line 742
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 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 330
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
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 178
def CGI::pretty(string, shift = " ")
lines = string.gsub(/(?!\A)<.*?>/, "\n\\0").gsub(/<.*?>(?!\n)/, "\\0\n")
end_pos = 0
while end_pos = lines.index(/^<\/(\w+)/, end_pos)
element = $1.dup
start_pos = lines.rindex(/^\s*<#{element}/, 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
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 154
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
URL-decode a string with encoding(optional).
string = CGI::unescape("%27Stop%21%27+said+Fred") # => "'Stop!' said Fred"
# File cgi/util.rb, line 16
def CGI::unescape(string,encoding=@@accept_charset)
str=string.tr('+', ' ').force_encoding(Encoding::ASCII_8BIT).gsub(/((?:%[0-9a-fA-F]{2})+)/) do
[$1.delete('%')].pack('H*')
end.force_encoding(encoding)
str.valid_encoding? ? str : str.force_encoding(string.encoding)
end
Undo escaping such as that done by CGI::escapeElement()
print CGI::unescapeElement( CGI::escapeHTML('<BR><A HREF="url"></A>'), "A", "IMG") # "<BR><A HREF="url"></A>" print CGI::unescapeElement( CGI::escapeHTML('<BR><A HREF="url"></A>'), ["A", "IMG"]) # "<BR><A HREF="url"></A>"
# File cgi/util.rb, line 127
def CGI::unescapeElement(string, *elements)
elements = elements[0] if elements[0].kind_of?(Array)
unless elements.empty?
string.gsub(/<\/?(?:#{elements.join("|")})(?!\w)(?:.|\n)*?>/) do
CGI::unescapeHTML($&)
end
else
string
end
end
Unescape a string that has been HTML-escaped
CGI::unescapeHTML("Usage: foo "bar" <baz>") # => "Usage: foo \"bar\" <baz>"
# File cgi/util.rb, line 41
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/ 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/
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
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 136
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
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 304
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