класс CGI
Обзор
Интерфейс общего шлюза (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() возвращает хеш всех параметров в запросе в виде пар имя/значение, где список значений — массив из одного или нескольких значений. Сам объект CGI также ведет себя как хеш с именами параметров в качестве ключей и значениями, но возвращает только одно значение (как строку) для каждого имени параметра.
Например, предположим, что запрос содержит параметр «favourite_colours» с несколькими значениями «синий» и «зелёный». Произойдет следующее:
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-элемент имеет соответствующий метод для генерации этого элемента в виде строки. Название этого метода совпадает с именем элемента, приведённым в нижнем регистре. Атрибуты элемента передаются в виде хеша, а тело — в качестве блока без аргументов, возвращающего строку. Модуль генерации 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 возвращает массив со старой версией 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
-
Строка для возврата каретки
- EOL
-
Стандартная последовательность символов новой строки в интернете
- HTTP_STATUS
-
Коды состояния HTTP.
- LF
-
Строка для перевода строки
- MAX_MULTIPART_COUNT
-
Максимальное количество параметров запроса при использовании метода multipart
- NEEDS_BINMODE
-
Необходимо ли обрабатывать данные в двоичном или текстовом формате
- PATH_SEPARATOR
-
Разделители путей в разных средах.
Атрибуты
Возвращает набор символов, принимаемых этим экземпляром CGI.
Методы публичного класса
# File lib/cgi/core.rb, line 739 def self.accept_charset @@accept_charset end
Возвращает набор символов, принимаемых всеми новыми экземплярами CGI.
# File lib/cgi/core.rb, line 744 def self.accept_charset=(accept_charset) @@accept_charset=accept_charset end
Устанавливает набор символов, принимаемых всеми новыми экземплярами CGI.
# File lib/cgi/core.rb, line 830
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 'cgi/html'
extend Html3
extend HtmlExtension
when "html4"
require 'cgi/html'
extend Html4
extend HtmlExtension
when "html4Tr"
require 'cgi/html'
extend Html4Tr
extend HtmlExtension
when "html4Fr"
require 'cgi/html'
extend Html4Tr
extend Html4Fr
extend HtmlExtension
when "html5"
require 'cgi/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 -
Строка, указывающая, какую версию методов генерации 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.
# File lib/cgi/core.rb, line 374
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", ...], ... }
Общедоступные методы экземпляров
Этот метод является псевдонимом для http_header, когда создатель тегов HTML5 неактивен.
ПРИМЕЧАНИЕ: используйте http_header для создания блоков HTTP-заголовков; этот псевдоним предоставлен только для обратной совместимости.
Использование header с создателем тегов HTML5 создаст элемент <header>.
# File lib/cgi/core.rb, line 152
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
-
Булевое значение. Если истинно, добавляет строку протокола и код состояния, и дату; устанавливает значения по умолчанию для «server» и «connection», если они не указаны явно.
- status
-
Код 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 Метод Недопустим
- NOT_ACCEPTABLE
-
406 Not Acceptable
- LENGTH_REQUIRED
-
411 Length Required
- PRECONDITION_FAILED
-
412 Precondition Failed
- SERVER_ERROR
-
500 Internal Server Error
- NOT_IMPLEMENTED
-
501 Метод Не реализован
- 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") Этот метод не выполняет преобразование кодировки символов.
# File lib/cgi/core.rb, line 348
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 -
Это хеш-таблица заголовков, аналогичная используемой http_header.
-
block -
Необходим блок, который должен вычисляться в тело ответа.
Content-Length автоматически рассчитывается из размера строки, возвращаемой блоком содержимого.
Если 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
# File lib/cgi/core.rb, line 364 def print(*options) stdoutput.print(*options) end
Выводит аргумент или список аргументов в стандартный поток вывода.
cgi = CGI.new cgi.print # default: cgi.print == $DEFAULT_OUTPUT.print
Закрытые методы экземпляров
# File lib/cgi/core.rb, line 51 def env_table ENV end
Синоним для ENV.
# File lib/cgi/core.rb, line 56 def stdinput $stdin end
Синоним для $stdin.
# File lib/cgi/core.rb, line 61 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.