класс CGI
Обзор
Интерфейс общего шлюза (CGI) — это простой протокол для передачи запроса HTTP от веб-сервера к автономной программе и возврата вывода в веб-браузер. По сути, программа CGI вызывается с параметрами запроса, передаваемыми либо в среде (GET), либо через $stdin (POST), и всё, что она выводит в $stdout, возвращается клиенту.
Этот файл содержит класс CGI. Этот класс предоставляет функциональность для извлечения параметров запроса HTTP, управления куки и генерации HTML-вывода.
Файл CGI::Session предоставляет функциональность управления сеансами; см. этот класс для получения более подробной информации.
См. www.w3.org/CGI/ для получения дополнительной информации о протоколе 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» со значениями «синий» и «зелёный». Произойдёт следующее:
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 вернул 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 для данного экземпляра CGI.
Методы публичного класса
# File lib/cgi/core.rb, line 748 def self.accept_charset @@accept_charset end
Возвращает набор символов accept для всех новых экземпляров CGI.
# File lib/cgi/core.rb, line 753 def self.accept_charset=(accept_charset) @@accept_charset=accept_charset end
Устанавливает набор символов accept для всех новых экземпляров CGI.
# 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. Может быть скаляром типа
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.
# 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", ...], ... }
Общедоступные методы экземпляра
Этот метод является псевдонимом для http_header, когда создатель тегов HTML5 неактивен.
ПРИМЕЧАНИЕ: используйте http_header для создания блоков заголовков HTTP, этот псевдоним предоставляется только для обратной совместимости.
Использование header с создателем тегов HTML5 создаст элемент <header>.
# 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
MethodNot 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
MethodNot 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, возвращается как один или несколько заголовков 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")
Этот метод не выполняет преобразование кодировок.
# 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
# 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
Закрытые методы экземпляра
# File lib/cgi/core.rb, line 59 def env_table ENV end
Синоним для ENV.
# File lib/cgi/core.rb, line 64 def stdinput $stdin end
Синоним для $stdin.
# 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.