класс 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() возвращает хэш всех параметров в запросе в виде пар имя/значение, где список значений является массивом 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
Атрибуты
Возвращает набор символов, принятых этим экземпляром CGI.
Методы публичного класса
# File lib/cgi/core.rb, line 759 def self.accept_charset @@accept_charset end
Возвращает набор символов, принятых всеми новыми экземплярами CGI.
# 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.
# 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", ...], ... }
Методы публичного экземпляра
# 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
# 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
Методы приватного экземпляра
# 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 # 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.