Class: CGI

Inherits:
Object
  • Object
show all
Extended by:
Escape, Util
Includes:
Escape, Util
Defined in:
lib/cgi.rb,
lib/cgi/core.rb,
lib/cgi/html.rb,
lib/cgi/util.rb,
lib/cgi/cookie.rb,
lib/cgi/escape.rb,
lib/cgi/session.rb,
lib/cgi/session/pstore.rb,
ext/cgi/escape/escape.c

Overview

:stopdoc

Defined Under Namespace

Modules: Escape, EscapeExt, Html3, Html4, Html4Fr, Html4Tr, Html5, HtmlExtension, QueryExtension, TagMaker, Util Classes: Cookie, HTML3, HTML4, HTML4Fr, HTML4Tr, HTML5, InvalidEncoding, Session

Constant Summary collapse

VERSION =

The version string

"0.5.2"
CR =

String for carriage return

"\015"
LF =

String for linefeed

"\012"
EOL =

Standard internet newline sequence

CR + LF
REVISION =

:nodoc:

'$Id$'
NEEDS_BINMODE =

Whether processing will be required in binary vs text

File::BINARY != 0
PATH_SEPARATOR =

Path separators in different environments.

{'UNIX'=>'/', 'WINDOWS'=>'\\', 'MACINTOSH'=>':'}
HTTP_STATUS =

HTTP status codes.

{
  "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"
}
MAX_MULTIPART_COUNT =

Maximum number of request parameters when multipart

128
@@accept_charset =

@@accept_charset is default accept character set. This default value default is “UTF-8” If you want to change the default accept character set when create a new CGI instance, set this:

CGI.accept_charset = "EUC-JP"
"UTF-8"
@@max_multipart_length =

@@max_multipart_length is the maximum length of multipart data. The default value is 128 * 1024 * 1024 bytes

The default can be set to something else in the CGI constructor, via the :max_multipart_length key in the option hash.

See CGI.new documentation.

128 * 1024 * 1024

Constants included from Escape

Escape::TABLE_FOR_ESCAPE_HTML__

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Escape

escape, escapeElement, escapeHTML, escapeURIComponent, unescape, unescapeElement, unescapeHTML, unescapeURIComponent

Methods included from Util

pretty, rfc1123_date

Constructor Details

#initialize(options = {}, &block) ⇒ CGI

:call-seq:

CGI.new(options = {}) -> new_cgi
CGI.new(tag_maker) -> new_cgi
CGI.new(options = {}) {|name, value| ... } -> new_cgi
CGI.new(tag_maker) {|name, value| ... } -> new_cgi

Returns a new CGI object.

The behavior of this method depends strongly on whether it is called within a standard CGI call environment; that is, whether ENV['REQUEST_METHOD'] is defined.

Within a Standard Call Environment

This section assumes that ENV['REQUEST_METHOD'] is defined; for example:

ENV['REQUEST_METHOD'] # => "GET"

With no argument and no block given, returns a new CGI object with default values:

cgi = CGI.new
cgi
# =>
#<CGI:0x00000189917aff00
 @accept_charset=#<Encoding:UTF-8>,
 @accept_charset_error_block=nil,
 @cookies={},
 @max_multipart_length=134217728,
 @multipart=false,
 @options={accept_charset: #<Encoding:UTF-8>, max_multipart_length: 134217728},
 @output_cookies=nil,
 @output_hidden=nil,
 @params={}>

With hash argument options given and no block given, returns a new CGI object with the given options.

The options may be:

  • accept_charset: encoding: specifies the encoding of the received query string.

    Value encoding may be an Encoding object or an encoding name:

    CGI.new(accept_charset: 'EUC-JP')
    

    If the option is not given, the default value is the class default encoding.

    Note: The accept_charset method returns the HTTP Accept-Charset header value, not the configured encoding. The configured encoding is used internally for query string parsing.

  • max_multipart_length: size: specifies maximum size (in bytes) of multipart data.

    The size may be:

    • A positive integer.

      CGI.new(max_multipart_length: 1024 * 1024)
      
    • A lambda to be evaluated when the request is parsed. This is useful when determining whether to accept multipart data (e.g. by consulting a registered user’s upload allowance).

      CGI.new(max_multipart_length: -> {check_filesystem})
      

    If the option is not given, the default is 134217728, specifying a maximum size of 128 megabytes.

    Note: This option configures internal behavior only. There is no public method to retrieve this value after initialization.

  • tag_maker: html_version: specifies a version of HTML; this determines which tag-generating instance methods (such as html, head, body, etc.) are to be loaded.

    Value html_version may be one of:

    Example:

    CGI.new(tag_maker: 'html5')
    

    If the option is not given (or if an invalid value is given), no tag-generating methods are loaded.

    Examples:

    CGI.new.respond_to?(:html)                       # => false  # Tag-generating methods not loaded.
    CGI.new(tag_maker: 'html3').respond_to?(:html)   # => true   # Tag-generating methods loaded.
    # Tag 'button' is new in HTML 4.
    CGI.new(tag_maker: 'html3').respond_to?(:button) # => false
    CGI.new(tag_maker: 'html4').respond_to?(:button) # => true
    # Tag 'canvas' is new in HTML 5.
    CGI.new(tag_maker: 'html4').respond_to?(:canvas) # => false
    CGI.new(tag_maker: 'html5').respond_to?(:canvas) # => true
    # Value is case-sensitive.
    CGI.new(tag_maker: 'HTML4').respond_to?(:html)   # => false
    

    You can determine exactly which methods have been loaded; this example captures the methods loaded by 'html4':

    methods_loaded = CGI.new('html4').methods - CGI.new.methods
    methods_loaded.size # => 98
    methods_loaded.sort.take(10)
    # => [:a, :abbr, :acronym, :address, :area, :b, :base, :bdo, :big, :blockquote]
    

With string argument tag_maker given as tag_maker and no block given, equivalent to CGI.new(tag_maker: tag_maker):

CGI.new('html5')

Outside a Standard Call Environment

This section assumes that ENV['REQUEST_METHOD'] is not defined; for example:

ENV['REQUEST_METHOD'] # => nil

In this mode, the method reads its parameters from the command line or (failing that) from standard input; returns a new CGI object.

Parameters from command line:

$ cat t.rb
require 'cgi'
cgi = CGI.new
p cgi.params
ruby t.rb foo=0 bar=1 foo=2 bar=3
{"foo" => ["0", "2"], "bar" => ["1", "3"]}

Parameters from standard input:

cgi = CGI.new
(offline mode: enter name=value pairs on standard input)
foo=0
bar=1
^D
cgi.params
# => {"foo" => ["0"], "bar" => ["1"]}

The end-of-file character is Ctrl-D on a Unix-like system (as above), or Ctrl-Z on Windows.

Otherwise, cookies and other parameters are parsed automatically from the standard CGI locations, which vary according to the request method.

Options vs Public Methods

Some initialization options configure internal behavior only and do not provide corresponding public getter methods:

  • accept_charset: Configures internal encoding for parsing. The accept_charset method returns the HTTP Accept-Charset header.

  • max_multipart_length: Configures internal multipart size limits. No public getter method is available.

  • tag_maker: Loads HTML generation methods (publicly accessible).

Block

If a block is given, its code is stored as a Proc; whenever CGI::InvalidEncoding would be raised, the proc is called instead.

In this example, the proc simply saves the error:

encoding_errors = {}
CGI.new(accept_charset: 'EUC-JP') do |name,value|
  encoding_errors[name] = value
end
# =>
#<CGI:0x000002b0ec11bcd8
 @accept_charset="EUC-JP",
 @accept_charset_error_block=#<Proc:0x000002b0ed2ee190 (irb):146>,
 @cookies={},
 @max_multipart_length=134217728,
 @multipart=false,
 @options={accept_charset: "EUC-JP", max_multipart_length: 134217728},
 @output_cookies=nil,
 @output_hidden=nil,
 @params={}>


1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
# File 'lib/cgi/core.rb', line 1223

def initialize(options = {}, &block) # :yields: name, value
  @accept_charset_error_block = block_given? ? block : nil
  @options={
    :accept_charset=>@@accept_charset,
    :max_multipart_length=>@@max_multipart_length
  }
  case options
  when Hash
    @options.merge!(options)
  when String
    @options[:tag_maker]=options
  end
  @accept_charset=@options[:accept_charset]
  @max_multipart_length=@options[:max_multipart_length]
  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_relative 'html'
    extend Html3
    extend HtmlExtension
  when "html4"
    require_relative 'html'
    extend Html4
    extend HtmlExtension
  when "html4Tr"
    require_relative 'html'
    extend Html4Tr
    extend HtmlExtension
  when "html4Fr"
    require_relative 'html'
    extend Html4Tr
    extend Html4Fr
    extend HtmlExtension
  when "html5"
    require_relative 'html'
    extend Html5
    extend HtmlExtension
  end
end

Instance Attribute Details

#accept_charsetObject (readonly)

Return the accept character set for this CGI instance.



1018
1019
1020
# File 'lib/cgi/core.rb', line 1018

def accept_charset
  @accept_charset
end

Class Method Details

.accept_charsetObject

:call-seq:

CGI.accept_charset -> encoding

Returns the default accept character set to be used for new CGI instances; see CGI.accept_charset=.



949
950
951
# File 'lib/cgi/core.rb', line 949

def self.accept_charset
  @@accept_charset
end

.accept_charset=(accept_charset) ⇒ Object

:call-seq:

CGI.accept_charset = encoding

Sets the default accept character set to be used for new CGI instances; returns the argument.

The argument may be an Encoding object or an Encoding name; see Encodings:

# The initial value.
CGI.accept_charset # => #<Encoding:UTF-8>
CGI.new
# =>
#<CGI:0x0000018991db6ae8
 @accept_charset=#<Encoding:UTF-8>,
 @accept_charset_error_block=nil,
 @cookies={},
 @max_multipart_length=134217728,
 @multipart=false,
 @options={accept_charset: #<Encoding:UTF-8>, max_multipart_length: 134217728},
 @output_cookies=nil,
 @output_hidden=nil,
 @params={}>

# Set by Encoding name.
CGI.accept_charset = 'US-ASCII' # => "US-ASCII"
CGI.new
# =>
#<CGI:0x0000018991cf4100
 @accept_charset="US-ASCII",
 @accept_charset_error_block=nil,
 @cookies={},
 @max_multipart_length=134217728,
 @multipart=false,
 @options={accept_charset: "US-ASCII", max_multipart_length: 134217728},
 @output_cookies=nil,
 @output_hidden=nil,
 @params={}>

# Set by Encoding object.
CGI.accept_charset = Encoding::ASCII_8BIT # => #<Encoding:BINARY (ASCII-8BIT)>
CGI.new
# =>
#<CGI:0x0000018991cfc800
 @accept_charset=#<Encoding:BINARY (ASCII-8BIT)>,
 @accept_charset_error_block=nil,
 @cookies={},
 @max_multipart_length=134217728,
 @multipart=false,
 @options={accept_charset: #<Encoding:BINARY (ASCII-8BIT)>, max_multipart_length: 134217728},
 @output_cookies=nil,
 @output_hidden=nil,
 @params={}>

The given encoding is not checked in this method, but if it is invalid, a call to CGI.new will fail:

CGI.accept_charset = 'foo'
CGI.new  # Raises ArgumentError: unknown encoding name - foo


1013
1014
1015
# File 'lib/cgi/core.rb', line 1013

def self.accept_charset=(accept_charset)
  @@accept_charset=accept_charset
end

.parse(query) ⇒ Object

:call-seq:

CGI.parse(query_string) -> hash

Returns a new hash built from name/value pairs in the given query_string:

query = 'foo=0&bar=1&foo=2&bar=3'
CGI.parse(query)
# => {"foo" => ["0", "2"], "bar" => ["1", "3"]}


572
573
574
575
576
577
578
579
580
581
582
583
584
585
# File 'lib/cgi/core.rb', line 572

def self.parse(query)
  params = {}
  query.split(/[&;]/).each do |pairs|
    key, value = pairs.split('=',2).collect{|v| CGI.unescape(v) }

    next unless key

    params[key] ||= []
    params[key].push(value) if value
  end

  params.default=[].freeze
  params
end

Instance Method Details

#http_header(options = 'text/html') ⇒ Object Also known as: header

:call-seq:

http_header(content_type = 'text/html') -> string
http_header(headers) -> string

Creates and returns an HTTP header section as a multi-line string.

The string always includes:

  • Header Content-Type (with a default value if none given).

  • A trailing newline, which delimits the header block; that last line is omitted from the examples below.

In Brief

headers = {
  'charset' => 'iso-2022-jp',
  'connection' => 'keep-alive',
  'cookie' => 'foo=0',
  'expires' => Time.now + (60 * 60 * 24 * 365),
  'language' => 'en-US, en-CA',
  'length' =>  4096,
  'nph' => true,
  'server' => 'Apache/2.4.1 (Unix)',
  'status' => 'OK',
  'type' => 'text/xml',
  MyHeader: true
}

puts cgi.http_header(headers)
HTTP/1.0 200 OK
Date: Mon, 01 Dec 2025 22:08:22 GMT
Server: Apache/2.4.1 (Unix)
Connection: keep-alive
Content-Type: text/xml; charset=iso-2022-jp
Content-Length: 4096
Content-Language: en-US, en-CA
Expires: Tue, 01 Dec 2026 22:05:30 GMT
Set-Cookie: foo=0
MyHeader: true

headers.delete('nph')

puts cgi.http_header(headers)
Status: 200 OK
Server: Apache/2.4.1 (Unix)
Connection: keep-alive
Content-Type: text/xml; charset=iso-2022-jp
Content-Length: 4096
Content-Language: en-US, en-CA
Expires: Tue, 01 Dec 2026 22:05:30 GMT
Set-Cookie: foo=0
MyHeader: true

Arguments

With no argument given, includes only header Content-Type with its default value 'text/html':

puts cgi.http_header
Content-Type: text/html

With string argument content_type given, includes header Content-Type with the given value:

puts cgi.http_header('text/xml')
Content-Type: text/xml

With hash argument headers given, includes a header for hash entry, whose name is based on the entry’s key, and whose value is the entry’s value.

Recognized Keys

The following keys are recognized; each is a lowercase string:

'charset'

The character set of the body; appended to the Content-Type header:

puts cgi.http_header('charset' => 'iso-2022-jp')
Content-Type: text/html; charset=iso-2022-jp
'connection'

Sets header Connection to the given string:

puts cgi.http_header('connection' => 'keep-alive')
Connection: keep-alive
Content-Type: text/html
'cookie'

Sets one or more Set-Cookie headers to the given value, which may be:

  • String cookie.

  • CGI::Cookie object.

  • Array of string cookies and CGI::Cookie objects.

  • A hash whose values are string cookies and CGI::Cookie objects (the keys are not used).

Examples:

foo_string = 'foo=0'
bar_string = 'bar=1'
foo_cookie = CGI::Cookie.new('foo', '0')
bar_cookie = CGI::Cookie.new('bar', '1')

puts cgi.http_header('cookie' => foo_string)
Content-Type: text/html
Set-Cookie: foo=0

puts cgi.http_header('cookie' => foo_cookie)
Content-Type: text/html
Set-Cookie: foo=0; path=

puts cgi.http_header('cookie' => [foo_cookie, bar_string])
Content-Type: text/html
Set-Cookie: foo=0; path=
Set-Cookie: bar=1

puts cgi.http_header('cookie' => {foo: foo_cookie, bar: bar_string})
Content-Type: text/html
Set-Cookie: foo=0; path=
Set-Cookie: bar=1

These cookies are in addition to the cookies held in the @output_cookies variable.

'expires'

Sets header Expires to the given time, which must be a Time object:

puts cgi.http_header('expires' => Time.now + (60 * 60 * 24 * 365))
Content-Type: text/html
Expires: Tue, 01 Dec 2026 23:42:37 GMT
'language'

Sets header Content-Language to the given string:

puts cgi.http_header('language' => 'en-US, en-CA')
Content-Type: text/html
Content-Language: en-US, en-CA
'length'

Sets header Content-Length to the given value, which may be an integer or a string:

puts cgi.http_header('length' =>  4096)
Content-Type: text/html
Content-Length: 4096

puts cgi.http_header('length' =>  '4096')
Content-Type: text/html
Content-Length: 4096
'nph'

If true:

  • Adds protocol string and status code as first line.

  • Adds date as second line.

  • Adds headers Server with no value, and Connection with default value 'close'; either or both values may be overridden with explicit values.

Examples:

puts cgi.http_header('nph' => true)
HTTP/1.0 200 OK
Date: Mon, 01 Dec 2025 19:42:22 GMT
Server:
Connection: close
Content-Type: text/html

puts cgi.http_header('nph' => true, 'server' => 'Apache/2.4.1 (Unix)', 'connection' => 'keep-alive')
HTTP/1.0 200 OK
Date: Mon, 01 Dec 2025 20:00:41 GMT
Server: Apache/2.4.1 (Unix)
Connection: keep-alive
Content-Type: text/html
'server'

Sets header Server to the given string:

puts cgi.http_header('server' => 'Apache/2.4.1 (Unix)')
Server: Apache/2.4.1 (Unix)
Content-Type: text/html
'status'

Sets header Status to the given string:

puts cgi.http_header('status' => '666 MyVeryOwnStatus')
Status: 666 MyVeryOwnStatus
Content-Type: text/html

If the given string is a key in the hash constant CGI::HTTP_STATUS, the status becomes the value for that key:

CGI::HTTP_STATUS
# =>
{"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"}

puts cgi.http_header('status' => 'OK')
Status: 200 OK
Content-Type: text/html

puts cgi.http_header('status' => 'NOT_FOUND')
Status: 404 Not Found
Content-Type: text/html
'type'

Sets Content-Type, overriding the default value 'text/html':

puts cgi.http_header('type' => 'text/xml')
Content-Type: text/xml

Unrecognized Keys

Headers may also be set for unrecognized keys; an unrecognized key becomes a header name with the given value:

puts cgi.http_header('length' => 0)  # Recognized key (lowercase string).
Content-Type: text/html
Content-Length: 0

puts cgi.http_header('Length' => 0)  # Unrecognized key (string key not lowercase).
Content-Type: text/html
Length: 0

puts cgi.http_header(length: 0)      # Unrecognized key (symbol key not string)
Content-Type: text/html
length: 0

This method does not perform charset conversion.

It’s best to use this method (CGI#http_header), not its aliased method header, which is provided only for backward compatibility.

Method CGI#http_header is preferred because when tag_maker is 'html5', calling method header generates an HTML header element:

cgi = CGI.new(tag_maker: 'html5')
puts cgi.http_header  # Works as expected.
Content-Type: text/html
puts cgi.header       # Maybe a surprise.
<HEADER></HEADER>


336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
# File 'lib/cgi/core.rb', line 336

def http_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

#nph?Boolean

:nodoc:

Returns:

  • (Boolean)


450
451
452
# File 'lib/cgi/core.rb', line 450

def nph?  #:nodoc:
  return /IIS\/(\d+)/ =~ $CGI_ENV['SERVER_SOFTWARE'] && $1.to_i < 5
end

#out(options = "text/html") ⇒ Object

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

:call-seq:

cgi.out(content_type_string='text/html')
cgi.out(headers_hash)
content_type_string

If a string is passed, it is assumed to be the content type.

headers_hash

This is a Hash of headers, similar to that used by #http_header.

block

A block is required and should evaluate to the body of the response.

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

If ENV['REQUEST_METHOD'] == "HEAD", then only the header is output (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”.

Example:

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" }
   # HTTP/1.1 200 OK
   # Date: Sun, 15 May 2011 17:35:54 GMT
   # Server: Apache 2.2.0
   # Connection: close
   # Content-Type: text/html; charset=iso-2022-jp
   # Content-Length: 6
   # Content-Language: ja
   # Expires: Tue, 14 Jun 2011 17:35:54 GMT
   # Set-Cookie: foo
   # Set-Cookie: bar
   # my_header1: my_value
   # my_header2: my_value
   #
   # string


543
544
545
546
547
548
549
550
551
552
# File 'lib/cgi/core.rb', line 543

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 http_header(options)
  output.print content unless "HEAD" == env_table['REQUEST_METHOD']
end

Print an argument or list of arguments to the default output stream

cgi = CGI.new
cgi.print    # default:  cgi.print == $DEFAULT_OUTPUT.print


559
560
561
# File 'lib/cgi/core.rb', line 559

def print(*options)
  stdoutput.print(*options)
end