Spec-Zone.ru › Ruby 2.7

класс CGI

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

Обзор

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

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

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

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

Введение

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

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

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

Запросы

Класс CGI динамически включает в себя функциональность анализа параметров и cookie, доступ к переменным среды и поддержку анализа запросов 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?.

Cookie

HTTP Cookie автоматически анализируются из запроса. Они доступны через аксессор cookies(), который возвращает хеш, где ключами являются имена cookie, а значениями — объекты 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 вернул 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.

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

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 — это хеш.

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

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 748
def self.accept_charset
  @@accept_charset
end

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

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

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 382
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-запроса в хэш пар key=>value.

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(content_type_string="text/html") Показать исходный код
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

Логическое значение. Если истинно, добавляет строку протокола и код состояния, а также дату; и устанавливает значения по умолчанию для «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 или несколько файлов cookie, возвращаемые в виде одного или нескольких заголовков Set-Cookie. Значение может быть строкой файла cookie; объектом CGI::Cookie; массивом Array строковых значений файлов cookie или объектов Cookie; или хешем, все значения которого являются строками файлов cookie или объектами Cookie.

Эти файлы cookie дополняют файлы cookie, хранящиеся в поле @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 356
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», то контент преобразуется в эту кодировку, а язык устанавливается в «яп».

Пример:

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 372
def print(*options)
  stdoutput.print(*options)
end

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

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

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

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–2017 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

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