Spec-Zone.ru › Ruby 2.6

класс CGI

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

Обзор

Common Gateway Interface (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 предоставляет методы для доступа к переменным среды, параметрам, куки и данным многочастного запроса. Для ответов, класс CGI предоставляет методы для записи вывода и генерации HTML.

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

Запросы

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

Многочастные запросы

Если метод запроса — 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

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

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

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

Атрибуты

accept_charset[R]

Возвращает набор символов по умолчанию для этого объекта CGI.

Публичные методы класса

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

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

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

Хэш-таблица значений заголовков. Признаются следующие ключи заголовков:

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