Spec-Zone.ru › Ruby 3.4

класс CGI

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

Обзор

Интерфейс общего шлюза (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

Атрибуты

accept_charset [R]

Возвращает набор символов, принятый для этого экземпляра CGI.

Методы класса

accept_charset ()
Исходный код
# File lib/cgi/core.rb, line 759
def self.accept_charset
  @@accept_charset
end

Возвращает набор символов, принятый для всех новых экземпляров CGI.

accept_charset= (accept_charset)
Исходный код
# File lib/cgi/core.rb, line 764
def self.accept_charset=(accept_charset)
  @@accept_charset=accept_charset
end

Устанавливает набор символов, принятый для всех новых экземпляров CGI.

new(tag_maker) { блок }
new(options_hash = {}) { блок }
Исходный код
# 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.

parse (query)
Исходный код
# 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", ...], ... }

Методы экземпляра

header
Псевдоним для: http_header
http_header
Исходный код
Также использует псевдоним: header
out(content_type_string='text/html')
out(headers_hash)
Исходный код
# 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
print (*options)
Исходный код
# 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

Скрытые методы экземпляра

_no_crlf_check (str)
Исходный код
# 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
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–2024 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API