Чтение онлайн

ЖАНРЫ

Linux и UNIX: программирование в shell. Руководство разработчика
Шрифт:

• Все поля значений разделяются символами &.

• Все значения и соответствующие поля разделяются знаками =.

• Все символы и некоторые специальные символы представляются кодами %ху, где xy является шестнадцатеричным эквивалентом данного символа. При просмотре переменной QUERY_STRING можно заметить, что многие из этих символов представлены переменной textarea.

Протокол cgi определяет, что любые символы в форме %ху (где xy является шестнадцатеричным числом) могут быть преобразованы в эквивалентные символы ASCII. Эти шестнадцатеричные символы состоят из специальных символов &, %, +, =, (, ) и всех других символов, выходящих за рамки десятичного диапазона ASCII с границей 127. Например, символу ( соответствует эквивалент в виде %29.

Шестнадцатеричные символы создаются в том случае, когда пользователь вводит значения в свободные текстовые поля. Однако эти символы могут также являться частью выбранного текста меню. Для выполнения декодирования закодированной строки нужно выполнить следующее:

• заменить все символы & символами перевода строки;

• заменить все символы + пробелами;

• заменить все символы = пробелами;

• преобразовать все значения %xy в эквивалентные символы ASCII.

После завершения описанной выше последовательности действий должна быть возможность осуществить запрос или реализовать доступ к каждой переменной. Благодаря этому можно обрабатывать отсылаемую информацию. В ходе декодирования выполняется только половина работы, хотя и наиболее трудоемкая. Для обеспечения доступа к значениям переменных можно воспользоваться командой eval.

Следующий сценарий выполняет все необходимые преобразования, а также обеспечивает доступ к переменным. Сценарий снабжен множеством комментариев, поэтому разобраться в его работе не составит особого труда.

$ pg conv.cgi

#!/bin/sh

#сценарий conv.cgi

#декодирование строки URL

echo "Content-type: text/html"

echo ""

echo "<HTML><PRE>"

#отображение метода кодированной строки

echo "Method : $REQUEST_METHOD"

echo "Query String : $QUERY_STRING"

echo "<HR>"

#применение редактора sed для замены символов & символами табуляции

LINE=`echo $QUERY_STRING | sed 's/&/ /g'`

for LOOP in $LINE do

# разбивка на поля NAME и TYPE

NAME=`echo $LOOP | sed 's/=/ /g' | awk '{print $1}'`

#получение TYPE, замена всех символов=пробелами, a %hex_num - \xhex_num

#замена всех символов + пробелами

TYPE=`echo $LOOP | sed 's/=/ /g' | awk '{print $2}' | \ sed -e 's/%\(\)/\\\x/g' | sed 's/+/ /g'`

#используется функция printf, которая отображает значения переменных:

#после завершения преобразований шестнадцатеричных значений

printf "${NAME}=${TYPE}\n"

#в переменную VARS записываются значения отдельных полей, которые затем

#передаются команде eval, благодаря чему отдельные поля можно адресовать;

#при этом, если поля содержат пробелы, требуется удвоенная обратная косая черта

VARS=`printf "${NAME}=\\${TYPE}\n"`

eval `printf $VARS`

done

echo "<HR>"

#используется printf для отображения специальных символов в случае их наличия

printf "Your name is : $contact\n"

printf "Your choice of film is : $film\n"

printf "Your choice of actor is : $actor\n"

printf "You watch films at the cinema : $view_cine\n"

printf "You watch films on video : $view_vid\n"

printf "And here are your comments : $textarea\n"

echo "</PRE>"

echo "</HTML>"

Нетрудно заметить, что в данном случае используется функция printf для вывода данных на экран. Причина этому весьма проста. Функция printf выполняет те же действия, что и обычная команда echo, но дополнительно выполняет шестнадцатеричные преобразования. В связи с этим следует сделать небольшое замечание. При использовании функции printf не происходит вставка символа новой строки; для устранения этого недостатка необходимо после каждой функции printf указать символы "\n", Шестнадцатеричные числа, хранящиеся в переменной QUERY_STRING, имеют формат %hex_num. Этот формат будет просто преобразован в формат \xhex_num с помощью потокового редактора sed, а также функции printf, выполняющей все необходимые преобразования. Зачем создавать себе дополнительные трудности, если для решения задачи существует простой способ?

Сохраните указанный выше сценарий под именем conv.cgi в каталоге cgi-bin. Теперь осталось выполнить небольшое изменение в сценарии books.cgi, в результате чего форма будет вызывать сценарий conv.cgi вместо сценария books_result.cgi. Для этого следует воспользоваться следующей строкой:

<FORM action = "/cgi-bin/conv.cgi" METHOD=GET>

Если теперь повторно передать форму (содержащую одну и ту же информацию), получим результаты, приведенные на рис. 29.10.

Теперь, когда строка имеет более удобочитаемый формат, можно выполнить некоторую обработку информации.

Метод get является стандартным методом, применяемым для работы с формами. В зависимости от имеющегося окружения, при использовании метода get существуют две потенциальные проблемы. Вся закодированная строка добавляется к адресу URL при отсылке информации, поэтому отсылаемая информация может быть просмотрена в окне URL, Хотя многие пользователи не видят в этом особой опасности, все же не стоит посылать информацию частного характера с помощью Web или сети.

Рис. 29.10. Полностью декодированные данные формы

Если пользовательская форма включает множество полей ввода, длина переменной query_string может чрезмерно возрасти. В этом случае многие пользователи для работы с такими формами используют метод post. Этот метод подробно рассматривается в следующем разделе.

29.5.2. Метод post

Метод post, также как и метод get, предназначен для работы с закодированными строками. Разница заключается в способе получения данных: метод post считывает данные из стандартного потока. Для отсылки данных с помощью метода post просто замените ключевое слово get словом post в конструкции form action сценария.

<FORM action="/cgi-bin/conv.cgi" METHOD=POST>

Переменная CONTENT_LENGTH будет хранить общее количество байтов, отосланных с применением метода post. Производится считывание строки из потока стандартного ввода, а затем выполняется то же самое преобразование, что и при использовании метода get. Процесс считывания завершается после того, как считанное количество байтов становится равным количеству байтов, хранящихся в переменной CONTENT_LENGTH.

После выполнения небольшого изменения в конструкции form action получится обобщенный декодер форм. Для осуществления считывания из стандартного потока ввода можно использовать команду cat. Ниже показана конструкция, которую следует добавить в сценарий conv.cgi, в результате чего появится возможность использования методов get и post.

Поделиться с друзьями: