CGI-сценарии
Обработка данных формы
Данные формы поступают в CGI-программу в закодированном виде, поэтому в качестве первого шага CGI-сценарий должен выполнить декодирование полученной информации. При пересылке данных методом GET данные формы присваиваются переменной среды QUERY_STRING, при передаче методом POST – передаются в программу через стандартный ввод и тоже могут быть присвоены некоторой внутренней переменной. Таким образом, декодирование данных сводится к следующей последовательности манипуляций со строкой:
- замена каждой группы %hh, состоящей из шестнадцатеричного ASCII-кода hh с префиксом %, на соответствующий ASCII-символ;
- замена символов "+" пробелами;
- выделение отдельных пар имя=знанение> разделенных ограничителем &;
- выделение из каждой пары имя=значение имени и значения соответствующего поля формы.
Программа декодирования HTML-формы может выглядеть, например, так:
#!/usr/bin/perl # Декодирование данных формы, переданных методом GET $form_data = $ENV{'QUERY_STRING'}; # преобразование цепочек %hh в соответствующие символы $form_data-= – s/%(..)/pack ("С", hex ($1))/eg; i преобразование плюсов в пробелы $form_data =~ tr/+/ /; # разбиение на пары имя=значение @pairs = split (/&/, $form_data); # выделение из каждой пары имени и значения поля формы и сохранение # их в ассоциативном массиве $fom_fields foreach $pair (@pairs) { ($name, $value)=split(/=/,$pair); $ form_fields{$name}=$value; }
Если данные формы переданы методом POST, то в приведенном тексте следует заменить оператор присваивания:
$form_data = $ENV{'QUERY_STRING'};
…оператором:
read(STDrN,$fom_data,$ENV{'CONTENT_LENGTH' }};
…считывающим из стандартного ввода программы CONTENT_LENGTH байтов, составляющих содержимое запроса клиента, в переменную $form_data.
В приведенном примере используются две новые функции: packQ и hex(). Поясним их назначение прежде, чем перейти к обсуждению текста программы.
Функция:
pack template, list
…упаковывает список значений list в двоичную структуру по заданному шаблону template. Аргумент template представляет собой последовательность символов, определяющих формат представления пакуемых данных:
- а/A Текстовая строка, заполненная нулями/пробелами
- b/B Двоичная строка, значения расположены в порядке возрастания/ убывания
- с/с Обычное символьное значение/ Символьное значение без знака
- f/d Значение в формате с плавающей точкой одинарной/двойной точности
- b/n Шестнадцатеричная строка, младший/старший полубайт первый
- i/i Целое со знаком/ без знака
- I/L Значение типа long со знаком/без знака
- П/N Значение типа short/long с "сетевым" порядком байтов ("старший в старшем")
- P/U Указатель на строку/Ш-кодированная строка s/s Значение типа short c$> знаком/без знака
- v/v Значение типа short/long с VAX-порядком байтов ("старший в младшем")
- х/х Нулевой байт/резервная копия байта
- @ Заполнение нулевыми байтами (до абсолютной позиции)
За каждым символом может следовать число, обозначающее счетчик применений данного символа в качестве формата. Символ * в качестве счетчика означает применение данного формата для оставшейся части списка.
$х = pack "cccc", 80,.101, 114, 108; $х = pack "c4", 80, 101, 114, 108; $х = pack "B32", "01010000011001010111001001101100"; $х = pack "H8", "5065726С"; $х = pack "H*", "5065726C"; ' $х = pack "сВ8Н2с",80,"01100101", 12, 108;
Значение переменной $х во всех случаях равно "peri".
Функция:
hex expr
…интерпретирует аргумент ехрг как шестнадцатеричную строку и возвращает ее десятичное значение.