Spec-Zone.ru › Ruby 3.2

класс CGI

Родитель:
Объект
Включенные модули:
CGI::Util

Обзор

Интерфейс общего шлюза (CGI) — это простой протокол для передачи HTTP-запроса от веб-сервера к автономной программе и возврата результата в веб-браузер. В сущности, программа CGI вызывается с параметрами запроса, переданными либо в окружении (GET), либо через $stdin (POST), и все, что она выводит в $stdout, возвращается клиенту.

В этом файле находится класс CGI. Этот класс предоставляет функциональность для получения параметров HTTP-запроса, управления куками и генерации HTML-вывода.

Файл CGI::Session предоставляет функциональность управления сеансами; подробнее см. этот класс.

Дополнительную информацию о протоколе CGI см. на сайте www.w3.org/CGI.

Введение

Класс CGI является обширным, предоставляя несколько категорий методов, многие из которых взяты из других модулей. Часть документации находится в этом классе, а часть — в модулях CGI::QueryExtension и CGI::HtmlExtension. Подробную информацию о работе с куками см. в CGI::Cookie, а информацию о сеансах — в cgi/session.rb (CGI::Session).

Для запросов CGI предоставляет методы для доступа к переменным окружения, параметрам, кукам и данным запроса multipart. Для ответов CGI предоставляет методы для записи вывода и генерации HTML.

Для получения более подробной информации см. примеры в конце.

Запросы

Класс CGI динамически включает в себя функциональность разбора параметров и куков, доступ к переменным среды и поддержку разбора multipart-запросов (включая загруженные файлы) из модуля CGI::QueryExtension.

Переменные окружения

Стандартные переменные окружения CGI доступны в качестве атрибутов только для чтения объекта CGI. Ниже приведен список этих переменных:

AUTH_TYPE               HTTP_HOST          REMOTE_IDENT
CONTENT_LENGTH          HTTP_NEGOTIATE     REMOTE_USER
CONTENT_TYPE            HTTP_PRAGMA        REQUEST_METHOD
GATEWAY_INTERFACE       HTTP_REFERER       SCRIPT_NAME
HTTP_ACCEPT             HTTP_USER_AGENT    SERVER_NAME
HTTP_ACCEPT_CHARSET     PATH_INFO          SERVER_PORT
HTTP_ACCEPT_ENCODING    PATH_TRANSLATED    SERVER_PROTOCOL
HTTP_ACCEPT_LANGUAGE    QUERY_STRING       SERVER_SOFTWARE
HTTP_CACHE_CONTROL      REMOTE_ADDR
HTTP_FROM               REMOTE_HOST

Для каждой из этих переменных существует соответствующий атрибут с тем же именем, но в нижнем регистре без префикса HTTP_. content_length и server_port — целые числа; остальные — строки.

Параметры

Метод params() возвращает хэш всех параметров в запросе в виде пар имя/значение, где список значений является массивом Array одного или нескольких значений. Сам объект CGI также ведет себя как хэш, связывающий имена параметров со значениями, но возвращает только одно значение (как строку String) для каждого имени параметра.

Например, предположим, что запрос содержит параметр «favourite_colours» с несколькими значениями «blue» и «green». Будет происходить следующее:

cgi.params["favourite_colours"]  # => ["blue", "green"]
cgi["favourite_colours"]         # => "blue"

Если параметр не существует, первый метод вернёт пустой массив, второй — пустую строку. Самый простой способ проверить существование параметра — использовать метод has_key?.

Куки

HTTP-куки автоматически парсятся из запроса. Они доступны через аксессор cookies(), который возвращает хэш, где ключ — имя куки, а значение — объект CGI::Cookie.

Multipart-запросы

Если метод запроса POST, а тип содержимого — multipart/form-data, то он может содержать загруженные файлы. Модуль QueryExtension сохраняет их в параметрах запроса. Имя параметра — это атрибут name поля ввода файла, как обычно. Однако значение не является строкой, а объектом IO, либо IOString для небольших файлов, либо Tempfile для больших. Этот объект также имеет дополнительные методы:

local_path()

путь к загруженному файлу в локальной файловой системе

original_filename()

имя файла на компьютере клиента

content_type()

тип содержимого файла

Ответы

Класс CGI предоставляет методы для отправки заголовков и содержимого клиенту HTTP и включает методы для программирования генерации HTML из модулей CGI::HtmlExtension и CGI::TagMaker. Точная версия HTML, используемая для генерации HTML, задаётся при создании объекта.

Запись вывода

Самый простой способ отправки вывода клиенту HTTP — использовать метод out(). Он принимает заголовки HTTP в качестве параметра в виде хэша и содержимое тела через блок. Заголовки можно сгенерировать в виде строки с помощью метода http_header(). Поток вывода можно записать напрямую с помощью метода print().

Генерация HTML

Для каждого HTML-элемента существует соответствующий метод для генерации этого элемента в виде строки String. Имя этого метода совпадает с именем элемента, приведённым в нижнем регистре. Атрибуты элемента передаются в виде хэша, а тело — в виде блока без аргументов, возвращающего строку String. Модуль генерации HTML знает, какие элементы всегда пустые, и молча пропускает переданное тело. Он также знает, какие элементы требуют закрывающих тегов, а какие нет. Однако он не знает, какие атрибуты допустимы для каких элементов.

Также есть дополнительные методы генерации HTML, включенные из модуля CGI::HtmlExtension. Они включают отдельные методы для различных типов элементов формы и методы для элементов, которые обычно принимают определённые атрибуты, которые можно указать напрямую в качестве аргументов, а не через хэш.

Утилиты HTML-эскейпа и другие методы, подобные функциям.

В cgi/util.rb определены некоторые утилитарные функции. При включении вы можете использовать утилитарные методы, как функции.

Примеры использования

Получение значений формы

require "cgi"
cgi = CGI.new
value = cgi['field_name']   # <== value string for 'field_name'
  # if not 'field_name' included, then return "".
fields = cgi.keys            # <== array of field names

# returns true if form has 'field_name'
cgi.has_key?('field_name')
cgi.has_key?('field_name')
cgi.include?('field_name')

ВНИМАНИЕ! cgi['field_name'] возвращал массив Array в старой версии cgi.rb (включена в Ruby 1.6)

Получение значений формы в виде хэша

require "cgi"
cgi = CGI.new
params = cgi.params

cgi.params — это хэш.

cgi.params['new_field_name'] = ["value"]  # add new param
cgi.params['field_name'] = ["new_value"]  # change value
cgi.params.delete('field_name')           # delete param
cgi.params.clear                          # delete all params

Сохранение значений формы в файл

require "pstore"
db = PStore.new("query.db")
db.transaction do
  db["params"] = cgi.params
end

Восстановление значений формы из файла

require "pstore"
db = PStore.new("query.db")
db.transaction do
  cgi.params = db["params"]
end

Получение значений multipart-формы

require "cgi"
cgi = CGI.new
value = cgi['field_name']   # <== value string for 'field_name'
value.read                  # <== body of value
value.local_path            # <== path to local file of value
value.original_filename     # <== original filename of value
value.content_type          # <== content_type of value

и значение имеет методы классов StringIO или Tempfile.

Получение значений куки

require "cgi"
cgi = CGI.new
values = cgi.cookies['name']  # <== array of 'name'
  # if not 'name' included, then return [].
names = cgi.cookies.keys      # <== array of cookie names

и cgi.cookies — это хэш.

Получение объектов куки

require "cgi"
cgi = CGI.new
for name, cookie in cgi.cookies
  cookie.expires = Time.now + 30
end
cgi.out("cookie" => cgi.cookies) {"string"}

cgi.cookies # { "name1" => cookie1, "name2" => cookie2, ... }

require "cgi"
cgi = CGI.new
cgi.cookies['name'].expires = Time.now + 30
cgi.out("cookie" => cgi.cookies['name']) {"string"}

Вывод HTTP-заголовков и HTML-строки в $DEFAULT_OUTPUT ($>)

require "cgi"
cgi = CGI.new("html4")  # add HTML generation methods
cgi.out do
  cgi.html do
    cgi.head do
      cgi.title { "TITLE" }
    end +
    cgi.body do
      cgi.form("ACTION" => "uri") do
        cgi.p do
          cgi.textarea("get_text") +
          cgi.br +
          cgi.submit
        end
      end +
      cgi.pre do
        CGI.escapeHTML(
          "params: #{cgi.params.inspect}\n" +
          "cookies: #{cgi.cookies.inspect}\n" +
          ENV.collect do |key, value|
            "#{key} --> #{value}\n"
          end.join("")
        )
      end
    end
  end
end

# add HTML generation methods
CGI.new("html3")    # html3.2
CGI.new("html4")    # html4.01 (Strict)
CGI.new("html4Tr")  # html4.01 Transitional
CGI.new("html4Fr")  # html4.01 Frameset
CGI.new("html5")    # html5

Некоторые утилитарные методы

require 'cgi/util'
CGI.escapeHTML('Usage: foo "bar" <baz>')

Некоторые утилитарные методы, подобные функциям

require 'cgi/util'
include CGI::Util
escapeHTML('Usage: foo "bar" <baz>')
h('Usage: foo "bar" <baz>') # alias

Константы

CR

String для возврата каретки

EOL

Стандартная последовательность новой строки в интернете

HTTP_STATUS

Коды состояния HTTP.

LF

String для перевода строки

MAX_MULTIPART_COUNT

Максимальное количество параметров запроса при использовании метода multipart

NEEDS_BINMODE

Требуется ли обработка в двоичном или текстовом режиме

PATH_SEPARATOR

Разделители пути в разных средах.

VERSION

Атрибуты

accept_charset[R]

Возвращает набор символов, принятый для этого экземпляра CGI.

Методы публичного класса

accept_charset() Показать исходный код
# File lib/cgi/core.rb, line 759
def self.accept_charset
  @@accept_charset
end

Возвращает набор символов, принятый для всех новых экземпляров CGI.

accept_charset=(accept_charset) Показать исходный код
# File lib/cgi/core.rb, line 764
def self.accept_charset=(accept_charset)
  @@accept_charset=accept_charset
end

Устанавливает набор символов, принятый для всех новых экземпляров CGI.

new(tag_maker) { block } Показать исходный код
new(options_hash = {}) { block }
# File lib/cgi/core.rb, line 850
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

Создает новый экземпляр CGI.

tag_maker

Это то же самое, что и использование формы options_hash со значением { :tag_maker => tag_maker }. Обратите внимание, что рекомендуется использовать форму options_hash, так как она также позволяет указать набор символов, который вы будете принимать.

options_hash

Хэш, распознающий три параметра:

:accept_charset

указываем кодировку полученной строки запроса. Если опущено, используется @@accept_charset. Если кодировка неверна, будет вызвано исключение CGI::InvalidEncoding.

Пример. Предположим, что @@accept_charset равно “UTF-8”

при отсутствии указания:

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

при указании как “EUC-JP”:

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

String, указывающий, какую версию методов генерации HTML использовать. Если не указано, методы генерации HTML загружены не будут.

Поддерживаются следующие значения:

“html3”

HTML 3.x

“html4”

HTML 4.0

“html4Tr”

HTML 4.0 Transitional

“html4Fr”

HTML 4.0 с фреймсетами

“html5”

HTML 5

:max_multipart_length

Указывает максимальную длину данных multipart. Может быть скалярным целым числом или лямбдой, которая будет вычислена при обработке запроса. Это позволяет реализовать более сложную логику при определении того, принимать ли данные multipart (например, проконсультироваться с зарегистрированным пределом загрузки пользователей)

По умолчанию — 128 * 1024 * 1024 байт

cgi=CGI.new(:max_multipart_length => 268435456) # simple scalar

cgi=CGI.new(:max_multipart_length => -> {check_filesystem}) # lambda
block

Если указано, блок вызывается при обнаружении неверной кодировки. Например:

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

Наконец, если объект CGI не создается в стандартной среде вызова CGI (то есть не может найти REQUEST_METHOD в своей среде), то он будет работать в автономном режиме. В этом режиме он считывает свои параметры из командной строки или (в случае неудачи) из стандартного ввода. В противном случае куки и другие параметры автоматически парсятся из стандартных мест CGI, которые варьируются в зависимости от REQUEST_METHOD.

parse(query) Показать исходный код
# File lib/cgi/core.rb, line 393
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

Парсит строку запроса HTTP в хеш пар ключевых => значение.

params = CGI.parse("query_string")
  # {"name1" => ["value1", "value2", ...],
  #  "name2" => ["value1", "value2", ...], ... }

Публичные методы экземпляра

header(options='text/html')

Этот метод является псевдонимом для http_header, когда создатель тегов HTML5 неактивен.

ПРИМЕЧАНИЕ: используйте http_header для создания блоков HTTP-заголовков, этот псевдоним предоставляется только для обратной совместимости.

Использование header с создателем тегов HTML5 создаст элемент <header>.

Псевдоним для: http_header
http_header(headers_hash) Показать исходный код
# File lib/cgi/core.rb, line 160
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

Создает блок HTTP-заголовков в виде строки.

Включает пустую строку, завершающую блок заголовков.

content_type_string

Если используется эта форма, эта строка является Content-Type

headers_hash

A Hash значения заголовков. Распознаются следующие ключи заголовков:

type

Заголовок Content-Type. По умолчанию «text/html»

charset

Кодировка символов тела, добавляемая к заголовку Content-Type.

nph

Булевое значение. Если true, добавляет строку протокола и код состояния, а также дату; и устанавливает значения по умолчанию для «server» и «connection», если они не установлены явно.

status

Код HTTP-состояния в виде String, возвращаемый в качестве заголовка 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

server

Программное обеспечение сервера, возвращаемое в заголовке Server.

connection

Тип подключения, возвращаемый в заголовке Connection (например, «close»).

length

Длина передаваемого содержимого, возвращаемая в заголовке Content-Length.

language

Язык содержимого, возвращаемый в заголовке Content-Language.

expires

Время истечения срока действия текущего содержимого, как объект Time, возвращаемый в заголовке Expires.

cookie

Cookie или несколько cookies, возвращаемые в одном или нескольких заголовках Set-Cookie. Значение может быть строкой cookie; объектом CGI::Cookie; массивом Array строковых значений cookie или объектов Cookie; или хэш, все значения которого являются строками cookie или объектами Cookie.

Эти cookies дополняют cookies в поле @output_cookies.

Можно устанавливать и другие заголовки; они добавляются в виде ключ: значение.

Примеры:

http_header
  # Content-Type: text/html

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

http_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")

Этот метод не выполняет преобразование кодировки символов.

Также алиасирован как: header
out(content_type_string='text/html') Показать исходный код
out(headers_hash)
# File lib/cgi/core.rb, line 367
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

Печать HTTP-заголовка и тела в $DEFAULT_OUTPUT ($>)

content_type_string

Если передается строка, она считается типом содержимого.

headers_hash

Это Hash заголовков, аналогичный используемому в http_header.

block

Требуется блок, значение которого должно быть телом ответа.

Content-Length автоматически вычисляется из размера String, возвращаемого блоком содержимого.

Если ENV['REQUEST_METHOD'] == "HEAD", то выводится только заголовок (блок содержимого по-прежнему необходим, но он игнорируется).

Если кодировка символов «iso-2022-jp» или «euc-jp» или «shift_jis», то содержимое преобразуется в эту кодировку, а язык устанавливается на «ja».

Пример:

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
print(*options) Показать исходный код
# File lib/cgi/core.rb, line 383
def print(*options)
  stdoutput.print(*options)
end

Вывод аргумента или списка аргументов в стандартный поток вывода

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

Приватные методы экземпляра

_no_crlf_check(str) Показать исходный код
# File lib/cgi/core.rb, line 191
def _no_crlf_check(str)
  if str
    str = str.to_s
    raise "A HTTP status or header field must not include CR and LF" if str =~ /[\r\n]/
    str
  else
    nil
  end
end
env_table() Показать исходный код
# File lib/cgi/core.rb, line 59
def env_table
  ENV
end

Синоним для ENV.

stdinput() Показать исходный код
# File lib/cgi/core.rb, line 64
def stdinput
  $stdin
end

Синоним для $stdin.

stdoutput() Показать исходный код
# File lib/cgi/core.rb, line 69
def stdoutput
  $stdout
end

Синоним для $stdout.

Ruby Core © 1993–2022 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API