класс 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» с несколькими значениями «синий» и «зелёный». Будет происходить следующее:
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 764 def self.accept_charset=(accept_charset) @@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-
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-запроса и преобразует её в хеш пар key=>value.
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 64 def stdinput $stdin end
Синоним для $stdin.
Исходный код
# File lib/cgi/core.rb, line 69 def stdoutput $stdout end
Синоним для $stdout.
Ruby Core © 1993–2024 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.