Spec-Zone.ru › Apache HTTP Server

Apache Руководство: Динамическое содержимое с CGI

Введение

Связанные модули Связанные директивы
  • mod_alias
  • mod_cgi
  • mod_cgid
  • AddHandler
  • Options
  • ScriptAlias

CGI (Common Gateway Interface) определяет способ взаимодействия веб-сервера с внешними программами, генерирующими содержимое, которые часто называют CGI-программами или CGI-скриптами. Это простой способ добавить динамическое содержимое на ваш веб-сайт, используя любой язык программирования, с которым вы наиболее знакомы. Этот документ будет введением в настройку CGI на вашем веб-сервере Apache и началом работы с написанием CGI-программ.

Настройка Apache для разрешения CGI

Для правильной работы CGI-программ вам необходимо настроить Apache на разрешение выполнения CGI. Есть несколько способов сделать это.

Примечание: Если Apache был скомпилирован с поддержкой совместных модулей, вам нужно убедиться, что модуль загружен; в вашем httpd.conf файле вы должны убедиться, что директива LoadModule не закомментирована. Правильно настроенная директива может выглядеть так:
LoadModule cgid_module modules/mod_cgid.so
В Windows или при использовании не потокового MPM, например prefork, правильно настроенная директива может выглядеть так:
LoadModule cgi_module modules/mod_cgi.so

ScriptAlias

Директива ScriptAlias сообщает Apache, что определенный каталог выделен для CGI-программ. Apache будет предполагать, что каждый файл в этом каталоге является CGI-программой и попытается выполнить его, когда клиент запросит этот конкретный ресурс.

Директива ScriptAlias выглядит так:

ScriptAlias "/cgi-bin/" "/usr/local/apache2/cgi-bin/"

Приведенный пример взят из вашего файла конфигурации по умолчанию httpd.conf, если вы установили Apache по умолчанию. Директива ScriptAlias очень похожа на директиву Alias, которая определяет префикс URL, сопоставляемый с определенным каталогом. Alias и ScriptAlias обычно используются для каталогов, расположенных вне каталога DocumentRoot. Различие между Alias и ScriptAlias заключается в том, что ScriptAlias имеет дополнительное значение, что всё под этим префиксом URL будет рассматриваться как CGI-программа. Таким образом, приведенный выше пример сообщает Apache, что любой запрос ресурса, начинающийся с /cgi-bin/, должен быть получен из каталога /usr/local/apache2/cgi-bin/, и должен обрабатываться как CGI-программа.

Например, если запрошен URL http://www.example.com/cgi-bin/test.pl, Apache попытается выполнить файл /usr/local/apache2/cgi-bin/test.pl и вернуть результат. Конечно, файл должен существовать, быть исполняемым и возвращать результат определённым образом, в противном случае Apache вернёт сообщение об ошибке.

CGI вне каталогов ScriptAlias

CGI-программы часто ограничиваются каталогами ScriptAlias по соображениям безопасности. Таким образом, администраторы могут строго контролировать, кто может использовать CGI-программы. Однако, если приняты надлежащие меры безопасности, нет причин, по которым CGI-программы не могут выполняться из произвольных каталогов. Например, вы можете разрешить пользователям иметь веб-содержимое в своих домашних каталогах с помощью директивы UserDir. Если они хотят иметь свои собственные CGI-программы, но не имеют доступа к основному каталогу cgi-bin, им потребуется возможность запускать CGI-программы в других местах.

Для разрешения выполнения CGI в произвольном каталоге необходимо выполнить два шага. Во-первых, обработчик cgi-script должен быть активирован с помощью директивы AddHandler или SetHandler. Во-вторых, ExecCGI должен быть указан в директиве Options.

Явное использование Options для разрешения выполнения CGI

Вы можете явно использовать директиву Options, в главном файле конфигурации сервера, чтобы указать, что выполнение CGI разрешено в определенном каталоге:

<Directory "/usr/local/apache2/htdocs/somedir">
    Options +ExecCGI
</Directory>

Вышеприведенная директива сообщает Apache разрешить выполнение CGI-файлов. Вам также необходимо указать серверу, какие файлы являются CGI-файлами. Следующая директива AddHandler сообщает серверу обрабатывать все файлы с расширениями cgi или pl как CGI-программы:

AddHandler cgi-script .cgi .pl

.htaccess-файлы

Руководство .htaccess показывает, как активировать CGI-программы, если у вас нет доступа к httpd.conf.

Пользовательские каталоги

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

<Directory "/home/*/public_html">
    Options +ExecCGI
    AddHandler cgi-script .cgi
</Directory>

Если вы хотите назначить подкаталог cgi-bin в каталоге пользователя, где всё будет обрабатываться как CGI-программа, вы можете использовать следующее.

<Directory "/home/*/public_html/cgi-bin">
    Options ExecCGI
    SetHandler cgi-script
</Directory>

Написание CGI-программы

Существует два основных различия между «обычным» программированием и CGI-программированием.

Во-первых, весь вывод вашей CGI-программы должен предваряться заголовком MIME-типа. Это HTTP-заголовок, который сообщает клиенту о типе получаемого содержимого. В большинстве случаев он будет выглядеть так:

Content-type: text/html

Во-вторых, ваш вывод должен быть в формате HTML или другом формате, который сможет отобразить браузер. В большинстве случаев это будет HTML, но иногда вы можете написать CGI-программу, которая выводит изображение gif или другое содержимое, отличное от HTML.

Помимо этих двух моментов, написание CGI-программы будет очень похоже на любую другую программу, которую вы можете написать.

Ваша первая CGI-программа

Ниже приведен пример CGI-программы, которая выводит одну строку в ваш браузер. Введите следующее, сохраните его в файл под названием first.pl, и поместите его в каталог cgi-bin.

#!/usr/bin/perl
print "Content-type: text/html\n\n";
print "Hello, World.";

Даже если вы не знакомы с Perl, вы должны понять, что происходит здесь. Первая строка сообщает Apache (или любой оболочке, под которой вы работаете) о том, что эту программу можно выполнить, передав файл интерпретатору, расположенному по пути /usr/bin/perl. Вторая строка выводит объявление типа содержимого, о котором мы говорили, за которым следуют две пары возврата каретки и новой строки. Это помещает пустую строку после заголовка, чтобы указать конец HTTP-заголовков и начало тела. Третья строка выводит строку "Hello, World!". И всё.

Если вы откроете свой любимый браузер и скажете ему получить адрес

http://www.example.com/cgi-bin/first.pl

или где вы поместили свой файл, вы увидите одну строку Hello, World. в окне браузера. Это не очень увлекательно, но как только вы это сделаете, у вас будет большой шанс получить практически всё.

Но это всё ещё не работает!

Существует четыре основных проблемы, которые вы можете увидеть в своём браузере, когда пытаетесь получить доступ к вашей CGI-программе через веб:

Вывод вашей CGI-программы
Отлично! Это значит, что всё прошло хорошо. Если вывод правильный, но браузер его не обрабатывает правильно, убедитесь, что у вас установлен правильный Content-Type в вашей CGI-программе.
Исходный код вашей CGI-программы или сообщение "POST Method Not Allowed"
Это означает, что вы не правильно настроите Apache для обработки вашей CGI-программы. Перечитайте раздел о настройке Apache и попробуйте найти, что вы пропустили.
Сообщение, начинающееся с "Forbidden"
Это означает, что проблема с правами доступа. Проверьте журнал ошибок Apache и раздел ниже о правах доступа к файлам.
Сообщение "Внутренняя ошибка сервера"
Если вы проверите журнал ошибок Apache, вы, вероятно, найдёте в нём "Преждевременный конец заголовков скрипта", возможно, вместе с сообщением об ошибке, сгенерированным вашей CGI-программой. В этом случае вам необходимо проверить каждый из разделов ниже, чтобы понять, что может препятствовать вашей CGI-программе выводить правильные HTTP-заголовки.

Права доступа к файлам

Помните, что сервер не работает как вы. То есть, при запуске сервера он работает с правами непривилегированного пользователя - обычно nobody или www - и поэтому ему понадобятся дополнительные права для выполнения файлов, которые вам принадлежат. Обычно, чтобы предоставить файлу достаточные права для выполнения nobody, необходимо предоставить всем пользователям права на выполнение файла:

chmod a+x first.pl

Кроме того, если ваша программа читает или записывает в другие файлы, эти файлы должны иметь правильные права доступа, чтобы разрешить это.

Информация о пути и окружении

Когда вы запускаете программу из командной строки, у вас есть определённая информация, которая передаётся оболочке, не задумываясь об этом. Например, у вас есть PATH, который указывает оболочке, где искать файлы, на которые вы ссылаетесь.

Когда программа запускается через веб-сервер как CGI-программа, у неё может быть другая PATH. Любые программы, которые вы вызываете в вашей CGI-программе (например, sendmail ), должны быть указаны полным путём, чтобы оболочка смогла их найти при попытке выполнить вашу CGI-программу.

Распространённым проявлением этого является путь к интерпретатору скрипта (часто perl), указанный в первой строке вашей CGI-программы, который будет выглядеть примерно так:

#!/usr/bin/perl

Убедитесь, что это действительно путь к интерпретатору.

При редактировании CGI-скриптов в Windows могут быть добавлены символы конца строки в путь интерпретатора. Убедитесь, что файлы затем передаются на сервер в ASCII-режиме. Отсутствие этого может привести к предупреждениям "Команда не найдена" от операционной системы из-за того, что не распознанный символ конца строки интерпретируется как часть имени файла интерпретатора.

Отсутствующие переменные окружения

Если ваша CGI-программа зависит от нестандартных переменных окружения, вам нужно убедиться, что эти переменные передаются Apache.

Если вы пропускаете HTTP-заголовки из окружения, убедитесь, что они отформатированы в соответствии с RFC 2616, раздел 4.2: Имена заголовков должны начинаться с буквы, за которой могут следовать только буквы, цифры или дефисы. Любой заголовок, нарушающий это правило, будет проигнорирован.

Ошибки программы

Большинство ошибок CGI-программ возникают из-за проблем с самой программой. Это особенно верно, когда вы осваиваете CGI, и больше не допускаете вышеупомянутых ошибок. Первым делом убедитесь, что ваша программа работает из командной строки, прежде чем тестировать её через веб-сервер. Например, попробуйте:

cd /usr/local/apache2/cgi-bin
./first.pl

(Не вызывайте интерпретатор perl. Оболочка и Apache должны найти интерпретатор, используя информацию о пути информацию о пути в первой строке скрипта.)

Первым, что должно быть выведено вашей программой, является набор HTTP-заголовков, включая Content-Type, за которым следует пустая строка. Если вы увидите что-то другое, Apache вернёт ошибку Premature end of script headers, если вы попытаетесь запустить её через сервер. Более подробную информацию см. выше в разделе Создание CGI-программы.

Журналы ошибок

Журналы ошибок — ваши друзья. Любая ошибка генерирует сообщение в журнале ошибок. Вы всегда должны сначала проверить их. Если место размещения вашего веб-сайта не предоставляет вам доступ к журналу ошибок, вам следует разместить свой сайт где-нибудь другом. Научитесь читать журналы ошибок, и вы обнаружите, что практически все ваши проблемы быстро идентифицируются и решаются.

Suexec

Программа поддержки suexec позволяет запускать CGI-программы с разными правами пользователя, в зависимости от виртуального хоста или домашнего каталога пользователя, в котором они находятся. Suexec имеет очень строгую проверку разрешений, и любая ошибка в этой проверке приведёт к тому, что ваши CGI-программы завершатся с ошибкой Premature end of script headers.

Чтобы проверить, используете ли вы suexec, выполните apachectl -V и проверьте расположение SUEXEC_BIN. Если Apache обнаружит двоичный файл suexec там при запуске, suexec будет активирован.

Если вы не полностью понимаете suexec, вам не следует его использовать. Чтобы отключить suexec, просто удалите (или переименуйте) двоичный файл suexec, на который указывает SUEXEC_BIN, и перезапустите сервер. Если после прочтения статьи о suexec вы всё ещё хотите использовать его, выполните suexec -V, чтобы найти расположение файла журнала suexec, и используйте этот файл журнала, чтобы найти, какое правило вы нарушаете.

Что происходит за кулисами?

По мере того, как вы становитесь более опытными в CGI-программировании, понимание того, что происходит за кулисами, станет полезным. В частности, как браузер и сервер общаются друг с другом. Ведь хотя написать программу, которая выводит "Hello, World!", — это хорошо, это не особенно полезно.

Переменные окружения

Переменные окружения — это значения, которые существуют во время работы с компьютером. Они включают такие полезные вещи, как ваш путь (где компьютер ищет фактический файл, реализующий команду, когда вы её вводите), ваше имя пользователя, тип вашей терминальной программы и так далее. Полный список обычных, повседневных переменных окружения можно получить, набрав env в командной строке.

Во время CGI-транзакции сервер и браузер также устанавливают переменные окружения, чтобы они могли общаться друг с другом. К ним относятся тип браузера (Netscape, IE, Lynx), тип сервера (Apache, IIS, WebSite), имя CGI-программы, которая выполняется, и так далее.

Эти переменные доступны CGI-программисту и составляют половину истории взаимодействия клиент-сервер. Полный список необходимых переменных находится в RFC Common Gateway Interface.

Эта простая Perl CGI-программа отобразит все переменные окружения, которые передаются. Два похожих программы включены в директорию cgi-bin дистрибутива Apache. Обратите внимание, что некоторые переменные являются обязательными, а другие — необязательными, поэтому вы можете увидеть перечисленные переменные, которые не были в официальном списке. Кроме того, Apache предоставляет множество способов добавления собственных переменных окружения к базовым переменным по умолчанию.

#!/usr/bin/perl
use strict;
use warnings;

print "Content-type: text/html\n\n";
foreach my $key (keys %ENV) {
    print "$key --> $ENV{$key}<br>";
}

STDIN и STDOUT

Другое взаимодействие между сервером и клиентом происходит через стандартный ввод (STDIN) и стандартный вывод (STDOUT). В обычной повседневной обстановке STDIN означает клавиатуру или файл, с которым программа должна работать, а STDOUT обычно означает консоль или экран.

Когда вы POST веб-форму в CGI-программу, данные в этой форме упаковываются в специальный формат и передаются вашей CGI-программе через STDIN. Затем программа может обрабатывать эти данные так, как будто они поступают с клавиатуры или из файла.

«Специальный формат» очень прост. Имя поля и его значение соединяются знаком равенства (=), а пары значений соединяются знаком амперсанда (&). Неудобные символы, такие как пробелы, амперсанды и знаки равенства, преобразуются в их шестнадцатеричный эквивалент, чтобы не мешать работе. Весь строковый массив данных может выглядеть примерно так:

name=Rich%20Bowen&city=Lexington&state=KY&sidekick=Squirrel%20Monkey

Иногда вы также видите такую строку, добавленную к URL. Когда это сделано, сервер помещает эту строку в переменную окружения, называемую QUERY_STRING. Это называется GET запросом. Ваша HTML-форма указывает, используется ли GET или POST для передачи данных, установив атрибут METHOD в теге FORM.

Затем ваша программа отвечает за разделение этой строки на полезную информацию. К счастью, существуют библиотеки и модули, которые помогут вам обработать эти данные, а также другие аспекты вашей CGI-программы.

CGI-модули/библиотеки

При написании CGI-программ следует рассмотреть использование библиотеки или модуля кода, чтобы выполнить большую часть рутинной работы. Это приводит к меньшему количеству ошибок и более быстрому развитию.

Если вы пишете CGI-программы на Perl, модули доступны на CPAN. Самый популярный модуль для этой цели — CGI.pm. Вы также можете рассмотреть CGI::Lite, который реализует минимальный набор функций, которого достаточно для большинства программ.

Если вы пишете CGI-программы на C, есть несколько вариантов. Одним из них является библиотека CGIC с сайта https://web.mit.edu/wwwdev/www/cgic.html.

Дополнительная информация

Текущая спецификация CGI доступна в RFC Common Gateway Interface.

При отправке вопроса о проблеме с CGI в список рассылки или новостную группу, убедитесь, что вы предоставили достаточно информации о произошедшем, о том, что вы ожидали, о том, чем фактически произошло, о том, какой сервер вы используете, на каком языке написана ваша CGI-программа и, при возможности, о проблемном коде. Это значительно упростит поиск вашей проблемы.

Обратите внимание, что вопросы о проблемах с CGI никогда не должны публиковаться в базе ошибок Apache, если вы не уверены, что обнаружили ошибку в исходном коде Apache.

© 2018 The Apache Software Foundation
Licensed under the Apache License, Version 2.0.
https://httpd.apache.org/docs/2.4/en/howto/cgi.html

Spec-Zone.ru

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