Perl и CGI-программы – особенности использования
Разработчики сайтов и администраторы нередко сталкиваются со скриптами CGI (микросценариями обработки текстовых данных). Они применяются при создании интерактивных страниц, содержание которых зависит от действий пользователя. Например, это могут быть формы регистрации или отправки комментариев. Также есть «невидимая» область применения – сбор и обработка информации о посетителях при помощи файлов cookies.
Что такое CGI и PERL
Важно понимать, что CGI – не язык программирования, а протокол передачи данных веб-серверу через stdin и их прием из stdout. В качестве обработчика команд используется любая программа с поддержкой функций потокового ввода-вывода. Например, написанная на языке Perl. Главное, что от скрипта требуется «умение» заполнять таблицы в базе данных и получать данные из них путем подачи запроса, чего никогда не сделать средствами HTML.
Особенности применения языка Perl:
В качестве альтернативы Perl все чаще применяется язык программирования Python, но администраторы «старой закалки» продолжают придерживаться классики создания CGI-скриптов, так как поддержка Perl «по умолчанию» имеется в большинстве дистрибутивов Linux. Поэтому программы на нем начинают работать без предварительной подготовки сервера. Формально же скрипты можно писать на чем угодно – хоть на C/C++, Pascal, Java или Visual Basic.
Использование готовых скриптов
Если CGI-скрипт уже готов (используется стандартный модуль), перед использованием его нужно скопировать на сервер хостинга. Выполняется процедура при помощи файлового менеджера в панели управления или через FTP-доступ, например программой FileZilla. Выбор расположения остается на усмотрение пользователя; к программе можно обращаться независимо от имени каталога или подкаталога, но рекомендуется придерживаться определенных стандартов.
Так, внутри скриптов обязательно указывается путь к интерпретатору используемой платформы для программирования:
Если здесь допустить ошибку, программный код исполнятся не будет. То же происходит, если в ПО предусмотрено обращение к базе данных MySQL – пользователю понадобится внести в программу путь к ней, логин и пароль доступа. При изменении последнего корректировка CGI-скрипта обязательна, иначе он перестанет работать. Местоположение файлов в популярных CMS выясняется в службе технической поддержки или в служебной документации.
Написание простейшего CGI-скрипта
При работе в среде операционной системы Windows для написания кода понадобится специальная программа. Например, подойдет специализированный текстовый редактор Notepad++ (стандартный Блокнот для таких целей не подходит). Сам код строится вокруг переменных окружения и потоков ввода-вывода информации. По сути, CGI-скрипты являются обработчиками отдельных команд и не являются «полноценной» программой.
Главное, избегать использования SHELL, который снижает безопасность сайта. В качестве примера простейшего CGI-скрипта приведем код для вывода текущей даты и команду HTML, при помощи которой будет происходить обращение к программе (из любой части страницы, хоть в нескольких местах одновременно).
При помощи специального виджета, установленного в CMS, или путем ручного редактирования шаблона в нужный участок HTML вставляется код:
В приведенном примере решена типовая ошибка новичков. Она заключается в отсутствии метки о типе выводимого результата (строка Content-type: text/html). После нее располагается пустая строка для указания, что следом идет непосредственно программный код.
Просмотр установленных модулей PERL
Проверить ранее подключенные PERL-модули можно командой vim. Перед ее вводом необходимо подключиться к серверу хостинга по защищенному каналу SSH. После авторизации нужно ввести в консоли:
В результате будет создан файл с указанным названием. Следующий шаг – открыть его в текстовом редакторе и изменить содержимое на следующий код:
Cgi bin папка для чего
CGI (от англ. Common Gateway Interface — «общий интерфейс шлюза») — стандарт интерфейса, используемого для связи внешней программы с веб-сервером. Программу, которая работает по такому интерфейсу совместно с веб-сервером, принято называть шлюзом, хотя многие предпочитают названия «скрипт» (сценарий) или «CGI-программа».
Упрощенная модель, иллюстрирующая работу CGI:
Сам интерфейс разработан таким образом, чтобы можно было использовать любой язык программирования, который может работать со стандартными устройствами ввода-вывода. Такими возможностями обладают даже скрипты для встроенных командных интерпретаторов операционных систем, поэтому в простых случаях могут использоваться даже командные скрипты.
Как работает CGI?¶
Обобщенный алгоритм работы через CGI можно представить в следующем виде:
Области применения CGI¶
Наиболее частая задача, для решения которой применяется CGI — создание интерактивных страниц, содержание которых зависит от действий пользователя. Типичными примерами таких веб-страниц является форма регистрации на сайте или форма для отправки комментария. Другая область применения CGI, остающаяся за кулисами взаимодействия с пользователем, связана со сбором и обработкой информации о клиенте: установка и чтение «печенюшек»-cookies; получение данных о браузере и операционной системе; подсчет количества посещений веб-страницы; мониторинг веб-трафика и т.п.
Это обеспечивается возможностью подключения CGI-скрипта к базе данных, а также возможностью обращаться к файловой системе сервера. Таким образом CGI-скрипт может сохранять информацию в таблицах БД или файлах и получать ее оттуда по запросу, чего нельзя сделать средствами HTML.
CGI — это не язык программирования! Это простой протокол, позволяющий веб-серверу передавать данные через stdin и читать их из stdout. Поэтому в качестве CGI-обработчика может использоваться любая серверная программа, способная работать со стандартными потоками ввода-вывода.
Пример простейшего cgi сервера
Думаю многие знают, как работает CGI взаимодействие между клиентом и сервером: клиент получает от сервера и отдает серверу данные через стандартные stdin и stdout. Многие наверное даже сами писали CGI клиентов, ведь по сути — любой скрипт для веб-сервера это и есть CGI-клиент.
А многие ли задавались вопросом, как именно происходит эта «магия»? Каким образом стандартные функции для ввода/вывода вместо экрана взаимодействуют с сервером?
CGI-клиент
Начну я все-таки с самого простого и общеизвестного: опишу своего клиента для CGI сервера. Простой «hello world» меня не устроил, потому что нужно было проверить не только возможность передачи сообщений через stdout, но и корректность приема переменных окружения и сообщений из stdin.
Кроме этого чтобы убедиться, что получилось самое настоящее CGI взаимодействие, было решено написать не один, а сразу два клиента. На с++ и на python.
Пояснения к коду клиентов
Если из CGI-сервера запустить клиента на С++, то на экран выведется информация о переменных командной строки, три переменные окружения с именами «Content-Length», «VARIABLE2» и «VARIABLE3», а также все содержимое которое получено от сервера в stdin.
Если из CGI-сервера запустить клиента на Python, то на экран выведется информация о переменных окружения с именами «Content-Length», «VARIABLE2» и «VARIABLE3», а также все содержимое которое получено от сервера в stdin.
Надо отметить, что переменная окружения «Content-Length» должна быть сформирована сервером таким образом, чтобы быть числом меньше либо равным количеству байт в stdin. Это необходимо потому, что клиент никаким другим образом не может узнать данную информацию кроме как от сервера.
CGI-сервер
В отличии от клиентских скриптов, код CGI сервера в сети найти совсем не просто, поэтому мой код собран из различных обрывистых и часто содержащих ошибки примеров. Кое-что добавил от себя, чтобы было более наглядно.
Пояснения к коду сервера
При такой инициализации сервер будет взаимодействовать с процессом «./Main_Child.exe». Так я назвал скомпилированного клиента на С++.
Если в качестве переменных командной строки задать массив <«python», "./test.py", 0>, то сервер будет взаимодействовать со скриптом на питоне.
После глобальных переменных я написал кроссплатформенный вариант функции _spawnve. Если коротко — то эта функция создает процесс, память которого полностью идентична текущему процессу и передает новому процессу другие переменные командной строки и окружения.
Заканчивается сервер функцией «main», большую часть которой (как можно догадаться по английским комментариям) я взял из разных сторонних источников. Из кода этой функции видно, что «вся соль» перенаправления ввода/вывода между процессами организована с помощью «pipe» (каналов).
Механизм каналов довольно простой и стандартный, он почти одинаково реализован как в Windows так и в Linux. Чтобы связать эти два подхода, в самом начале исходника я добавил простое переопределение:
В конце функции «main» организован бесконечный цикл, в котором сервер принимает от клиента ответ и передает этот ответ на экран. Выход из цикла произойдет когда клиентский процесс завершится.
Заключение
Несмотря на свой солидный возраст, CGI — интерфейс остается одним из самых распространенных интерфейсов межпроцессного взаимодействия. Подавляющее большинство веб-серверов и веб-сайтов взаимодействуют именно с помощью этого интерфейса. Надеюсь данная статья будет полезна тем, кто захочет понять, а может и реализовать в собственных проектах не только клиентскую, но и серверную часть CGI.
Все исходники можно найти: тут.
В папках «cgi_main» и «child» находятся проекты для Visual Studio.
Чтобы запустить пример под Линукс, достаточно скопировать содержимое папки «src» и запустить скрипт «compile.py». Должно получиться что-то вроде этого:
CGI-программирование на ассемблере. – Легко!
Статья гуляет в интернете уже довольно давно, но, как автор думаю имею право на ее перепост здесь. Многое (если не все) написаное здесь устарело, и может показаться бесполезным с первого взгляда, однако пройдя этот путь, спустя 6 лет могу сказать, это не оказалось лишним. Итак.
В этой статье я хочу рассказать о CGI интерфейсе вообще, его реализации для windows и использовании при написании CGI-программ языка ассемблер в частности. В рамки этой статьи не входит полное описание CGI, так-как в Интернете материала по этому вопросу просто море и пересказывать все это здесь я просто не вижу смысла.
Теория CGI
CGI – (Common Gateway Interface) – Общий Шлюзовый Интерфейс. Как не трудно догадаться интерфейс этот служит шлюзом между сервером (здесь я подразумеваю программу — сервер) и какой-либо внешней программой написанной для ОС на которой этот самый сервер запущен. Таким образом CGI отвечает за то, каким именно образом данные будут переданы от программы-сервера к CGI-программе и обратно. Интерфейс не накладывает никаких ограничений на то, на чем должна быть написана CGI-программа, это может быть как обычный исполнимый файл, так и любой другой файл – главное, чтобы сервер смог его запустить (в среде windows это например может быть файл с расширением, привязанным к какой-либо программе).
С момента когда Вы вызвали (например нажали кнопку формы, к которой привязан вызов CGI-программы) CGI-программу до получения вами результата в окно браузера происходит следующее:
— Вэб-клиент (например браузер) создает подключение к серверу, указанному в URL;
— Вэб-клиент посылает запрос серверу, запрос этот обычно делается с помощью двух методов GET или POST;
— Данные из запроса клиента (например значения полей формы) передаются сервером, используя CGI-интерфейс, CGI-программе, указанной в URL;
— CGI-программа обрабатывает данные клиента, полученные от сервера и генерирует на основе этой обработки ответ клиенту, который она передает по все тому же CGI-интерфейсу серверу, а он в свою очередь передает его уже непосредственно клиенту;
— Сервер разрывает соединение с клиентом.
В стандартной спецификации CGI принято, что сервер может обмениваться с программой следующими способами:
— Переменные окружения – они могут быть установлены сервером при запуске программы;
— Стандартный поток ввода (STDIN) – с его помощью сервер может передать данные программе;
— Стандартный поток вывода (STDOUT) – программа может писать в него свой вывод, передающийся серверу;
— Командная строка – в ней сервер может передать некоторые параметры программе.
Стандартные потоки ввода/вывода весьма удобны и широко используются на UNIX-системах, чего не скажешь о windows, поэтому существует спецификация CGI, разработанная специально для windows-систем так и называемая «Windows CGI». Но, естественно, и стандартные потоки ввода/вывода так же можно использовать в windows CGI программировании. Здесь я не буду затрагивать стандарт «Windows CGI», и на это существует по крайней мере две причины – первая, и самая главная – на данный момент не все http-сервера под windows поддерживают эту спецификацию (в частности мой любимый Apache 1.3.19). Вторую причину вы можете наблюдать набрав в любой поисковой системе строчку «Windows CGI». Отмечу относительно этого интерфейса лишь общие детали – все данные от сервера к клиенту передаются посредством обычного для windows *.ini файла, имя которого передается программе в командной строке. При этом все данные в файле уже заботливо разбиты по секциям сервером и вам лишь остается используя функции «GetPrivateProfile*» извлечь их оттуда. Ответ серверу передается опять же посредством файла, имя которого указано в соответствующей записи ini-файла.
Какие же данные могут быть переданы клиентом CGI-программе? – практически любые. В общем случае программе передаются значения полей формы, которые заполняет клиент, но это также могут быть и какие-либо двоичные данные, например файл с картинкой или музыкой. Данные могут быть переданы на сервер двумя различными методами – это метод GET и метод POST. Когда мы создаем форму для заполнения на нашей страничке мы явно указываем каким из приведенных методов мы хотим отправить введенные пользователем данные, делается это в основном тэге формы примерно так:
При отправке данных методом GET, данные браузером считываются из формы и помещаются следом за URL скрипта, за знаком вопроса, если значимых полей в форме несколько, то они передаются все через значёк «&», имя поля и его значение пишутся в URL через знак «=». Например запрос, сгенерированный браузером из формы при нажатии на кнопку, к которой привязан скрипт «/cgi-bin/test.exe», при учете что первое поле формы называется «your_name», второе – «your_age», может выглядеть так:
GET /cgi-bin/test.exe?your_name=Pupkin&your_age=90 HTTP/1.0
Использование метода GET имеет сразу несколько слабых сторон – первое и самое главное – т.к. данные передаются в URL то он имеет ограничение на количество этих самых передаваемых данных. Вторая слабость опять же вытекает из URL – это конфиденциальность, при такой передаче данные остаются абсолютно открытыми. Итак, хорошо если у нас в форме 2-3 небольших поля… встает вопрос что же делать если данных больше? Ответ – использовать метод POST!
При использовании метода POST данные передаются серверу как блок данных, а не в URL, что несколько развязывает нам руки для увеличения объема передаваемой информации, для вышеприведенного примера формы POST блок, посылаемый серверу будет примерно такой:
POST /cgi-bin/test.exe HTTP/1.0
Accept: text/plain
Accept: text/html
Accept: */*
Content-type: application/x-www-form-urlencoded
Content-length: 36
your_name=Pupkin&your_age=90
Как уже говорилось выше, после получения данных сервер должен преобразовать их и передать CGI программе. В стандартной спецификации CGI введенные клиентом данные при запросе GET помещаются сервером в переменную среды программы «QUERY_STRING». При запросе POST данные помещаются в стандартный поток ввода приложения, откуда могут быть им считаны. Кроме того, при таком запросе сервером устанавливаются еще две переменные среды — CONTENT_LENGTH и CONTENT_TYPE, по которым можно судить о длине запроса в байтах и о его содержании.
Помимо самих данных сервером устанавливаются и другие переменные окружения вызываемой программы, приведу некоторые из них:
REQUEST_METHOD
Описывает каким именно методом получены данные
Пример:REQUEST_METHOD=GET
QUERY_STRING
Строка запроса, если использовался метод GET
Пример:QUERY_STRING= your_name=Pupkin&your_age=90&hobby=asm
CONTENT_LENGTH
Длина в байтах тела запроса
Пример:CONTENT_LENGTH=31
CONTENT_TYPE
Тип тела запроса
GATEWAY_INTERFACE
Версия протокола CGI
Пример:GATEWAY_INTERFACE=CGI/1.1
REMOTE_ADDR
IP-Адрес удаленного хоста, то бишь клиента, нажавшего кнопочку в форме
Пример:REMOTE_ADDR=10.21.23.10
REMOTE_HOST
Имя удаленного хоста, это может быть его доменное имя или например имя компьютера в среде Windows, если таковые получены быть не могут, то поле содержит его IP
Пример:REMOTE_HOST=wasm.ru
SCRIPT_NAME
Имя скрипта, использованное в запросе.
Пример:SCRIPT_NAME=/cgi-bin/gols.pl
SCRIPT_FILENAME
Имя файла скрипта на сервере.
Пример:SCRIPT_FILENAME=c:/page/cgi-bin/gols.pl
SERVER_SOFTWARE
Программное обеспечение сервера
Пример:Apache/1.3.19 (WIN32)
Вызываемая CGI-программа может прочитать любую из переменных своего окружения, установленных сервером и использовать ее в своих интересах.
В общем-то это вкратце все, для получения более подробной информации о Общем Шлюзовом Интерфейсе смотрите специализированную документацию, это описание я сделал для того, чтобы напомнить вам, а если не знали то ввести в курс дела. Давайте попробуем что-нибудь сделать на практике.
Практическая часть
Для практики нам понадобятся как минимум 3 вещи – какой-нибудь http-сервер для Windows, все примеры я пробовал на Apache 1.3.19 для Windows, сервер бесплатный, скачать его можно с i
Да, и сервер нам понадобится не абы – какой, а настроенный для запуска cgi-скриптов! Как это делается для сервера используемого вами смотрите документацию. Вторая вещь, которая нам понадобится это, естественно, ассемблер, так же необходимо, чтобы компилятор поддерживал создание консольных WIN32 приложений, я использую Tasm, но прекрасно подойдут и Fasm и Masm и множество других *asm’ов. Ну и наконец самое главное, что потребуется это желание.
Итак, я допускаю, что сервер был вами благополучно поставлен и настроен, так, что в корневой директории документов сервера лежит файлик index.html, который замечательно показывается в браузере, когда вы набираете адрес 127.0.0.1. Так же я учту, что где-то в дебрях папок сервера существует папочка «cgi-bin», в которой разрешен запуск скриптов.
Давайте проверим настройку сервера, а заодно и напишем небольшой скрипт. Скрипт наш будет обычным *.bat файлом. Предвижу вопросы – как? неужели? Да, это обычный командный файл, как уже говорилось выше спецификация CGI не делает различий между типами файлов, главное, чтобы сервер мог его запустить, а он в свою очередь, имел доступ к stdin/stdout и переменным окружения, bat-файл, пусть и не в полной мере, но для примера нас вполне устроит. Создадим файл примерно такого содержания:
@echo off
rem Заголовок апроса
echo Content-type: text/html
echo.
rem Тело запроса
echo «Привет!
echo «С запросом GET пришли данные: %QUERY_STRING%
Файл назовем test.bat и поместим его в директорию для запуска скриптов, скорее всего это будет директория «cgi-bin». Следующее, что нам нужно будет сделать, это каким либо образом вызвать этот скрипт, в принципе, сделать это можно напрямую набрав в окошке адреса браузера примерно следующее «http://127.0.0.1/cgi-bin/test.bat», но давайте сделаем его вызов с нашей главной странички, заодно проверим работу метода GET. Создадим в корне сервера файл index.html со следующим содержанием:
Функция возвратит необходимый нам для операций чтения/записи хэндл. Следующее что нам необходимо делать это писать/читать эти потоки. Делается это обычными операциями чтения/записи файлов, т.е. ReadFile и WriteFile. Тут есть одна тонкость, можно подумать, что для этих целей можно использовать WriteConsole/ReadConsole, да это действительно справедливо для консоли и будет прекрасно работать, результаты, так же как и с WriteFile будут выводиться на консоль, но продолжаться это будет пока мы не запустим нашу программу как скрипт на сервере. Происходит это потому что, когда нашу программу запускает сервер хндлы, возвращаемые функцией «GetStdHandle» уже не будут хндлами консоли как таковыми, они будут хэндлами pipe, что необходимо для связи двух приложений.
Вот небольшой пример того, как должна выглядеть CGI-программа на ассемблере:
xor ebx,ebx
call GetStdHandle,STD_OUTPUT_HANDLE
mov hStdout,eax
call GetStdHandle,STD_INPUT_HANDLE
mov hStdin,eax
call write_stdout, offset header
call write_stdout, offset start_html
call VirtualAlloc,ebx,1000,MEM_COMMIT+MEM_RESERVE,PAGE_READWRITE
mov hMem,eax
mov edi,eax
call GetEnvironmentStringsA
mov esi,eax
next_symbol:
mov al,[esi]
or al,al
jz end_string
mov [edi],al
next_string:
cmpsb
jmp short next_symbol
end_string:
mov [edi],’>rb
Как загрузить сайт на хостинг?
Разместить сайт на нашем хостинге можно, воспользовавшись сервисами Панели управления либо программами (клиентами) для работы по протоколу FTP. Ниже рассмотрим оба этих способа.
Размещение сайта в Панели управления
Форма для входа в панель управления расположена в правом верхнем углу нашего сайта. Для входа в Панель управления указываются логин и пароль, высылаемые в письме после регистрации аккаунта.
Для размещения сайта через Панель управления используется раздел «Файловый менеджер», предназначенный для работы с файлами на аккаунте. В нем отображается текущее содержимое аккаунта. На каждом новом аккаунте виртуального хостинга изначально находится папка public_html, в которой и следует размещать файлы сайта. Для входа в папку надо нажать на ее имя.
При входе в папку в «Файловом менеджере» будет выведено её содержимое:
Содержимое страницы index.html можно видеть по основному или техническому домену.
На этой странице приведена общая информация по работе с новым аккаунтом, а также наши контактные данные. Для работы сайта эта страница не понадобится, и перед загрузкой файлов сайта следует удалить файлы .htaccess и index.html из папки public_html.
После удаления можно начинать загружать файлы сайта на сервер. Для этого потребуется выполнить следующие действия:
Как только загрузка будет завершена, список содержимого аккаунта обновится и загруженный файл будет отображаться в этом списке. Если файлов сайта пока немного, то таким образом можно загрузить их все. Если требуется загрузить большое количество файлов сайта, рекомендуется загружать эти файлы в виде архива. Для этого следует:
После выполнения этой задачи все файлы из архива будут доступны на аккаунте.
У сайта должна быть индексная (главная) страница. Поэтому надо назвать именем index.html тот файл, который должен открываться первым при загрузке сайта, т.е. сделать этот файл индексным. Например, если требуется, чтобы страница mypage.html открывалась первой при загрузке сайта, то файл mypage.html надо переименовать в index.html. Имя файла обязательно задаётся в нижнем регистре.
Переименовать файл можно либо на компьютере перед загрузкой сайта на аккаунт, либо после того, как он будет загружен. Если рассматривать второй вариант, то после загрузки нужно будет:
Размещение
Для размещения файлов сайта на хостинге удобно использовать FTP-клиент.
Подключение производится в окне программы, где указываются хост (имя домена, на котором размещается сайт или IP-адрес сервера, где находится аккаунт, он указан в левом меню панели управления), логин и пароль основного или дополнительного FTP-аккаунта и порт 21.
В случае отсутствия на компьютере установленного FTP-клиента подключение по FTP может быть произведено напрямую из браузера. Для этого в адресной строке браузера указывается адрес вида:

Создание
Если на сайте предполагается использование базы данных, создать её можно в разделе панели управления «Базы данных». Для создания базы данных надо нажать на кнопку «Создать базу данных» и в открывшемся окне выбрать тип базы данных, указать имя базы данных и задать пароль, который будет использоваться при подключении к базе.




.png)











