Spec-Zone.ru › Ruby 3.3

класс 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

Set набор символов, принимаемых всеми новыми экземплярами 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

A 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-данных. Может быть скалярным Integer или лямбда-функцией, которая будет вычислена при разборе запроса. Это позволяет реализовать более сложную логику для определения того, принимать ли 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
Псевдоним для: http_header
http_header
Также псевдоним для: 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