В вычислительной технике Common Gateway Interface ( CGI ) — это спецификация интерфейса, которая позволяет веб-серверам выполнять внешнюю программу для обработки пользовательских запросов HTTP или HTTPS .
Такие программы часто пишутся на языке сценариев и обычно называются скриптами CGI , но они могут включать в себя скомпилированные программы. [1]
Типичный случай использования происходит, когда веб-пользователь отправляет веб-форму на веб-странице, которая использует CGI. Данные формы отправляются на веб-сервер в HTTP-запросе с URL-адресом, обозначающим скрипт CGI. Затем веб-сервер запускает скрипт CGI в новом компьютерном процессе , передавая ему данные формы. Скрипт CGI передает свой вывод, обычно в форме HTML , на веб-сервер, а сервер передает его обратно браузеру в качестве ответа на запрос браузера. [2]
Разработанный в начале 1990-х годов, CGI был самым ранним доступным распространенным методом, который позволял веб-странице быть интерактивной. Из-за необходимости запускать скрипты CGI в отдельном процессе каждый раз, когда от клиента поступает запрос, были разработаны различные альтернативы.
В 1993 году команда Национального центра суперкомпьютерных приложений (NCSA) написала спецификацию для вызова исполняемых файлов командной строки в списке рассылки www-talk. [3] [4] [5] Другие разработчики веб-серверов приняли ее, и с тех пор она стала стандартом для веб-серверов. Рабочая группа под председательством Кена Коара начала работу в ноябре 1997 года, чтобы более формально определить определение CGI NCSA. [6] Результатом этой работы стал RFC 3875, в котором указана версия CGI 1.1. В RFC особо упомянуты следующие участники: [2]
Исторически программы CGI часто писались с использованием языка программирования C. RFC 3875 «The Common Gateway Interface (CGI)» частично определяет CGI с использованием C, [2] утверждая, что переменные окружения «доступны с помощью процедуры библиотеки C getenv() или переменной environ».
Название CGI происходит от ранних дней Интернета, когда веб-мастера хотели подключить устаревшие информационные системы, такие как базы данных, к своим веб-серверам. Программа CGI выполнялась сервером и обеспечивала общий «шлюз» между веб-сервером и устаревшей информационной системой.
Традиционно веб-сервер имеет каталог , который обозначается как коллекция документов, то есть набор файлов, которые могут быть отправлены в веб-браузеры, подключенные к серверу. [7] Например, если веб-сервер имеет полное доменное имя www.example.com
, а его коллекция документов хранится /usr/local/apache/htdocs/
в локальной файловой системе (его корневой каталог документов ), то веб-сервер ответит на запрос , http://www.example.com/index.html
отправив браузеру копию файла /usr/local/apache/htdocs/index.html
(если он существует).
Для страниц, создаваемых «на лету», серверное программное обеспечение может откладывать запросы в отдельные программы и передавать результаты запрашивающему клиенту (обычно веб-браузеру, который отображает страницу конечному пользователю).
Такие программы обычно требуют указания некоторой дополнительной информации с запросом, например, строк запроса или файлов cookie . Наоборот, при возврате скрипт должен предоставить всю информацию, требуемую HTTP для ответа на запрос: HTTP-статус запроса, содержимое документа (если доступно), тип документа (например, HTML, PDF или простой текст) и т. д.
Первоначально не было стандартизированных методов обмена данными между браузером, HTTP-сервером, с которым он взаимодействовал, и скриптами на сервере, которые должны были обрабатывать данные и в конечном итоге возвращать результат браузеру. В результате между различными вариантами HTTP-сервера существовала взаимная несовместимость, что подрывало переносимость скриптов .
Осознание этой проблемы привело к спецификации того, как должен осуществляться обмен данными, что привело к разработке CGI. Программы, генерирующие веб-страницы, вызываемые серверным программным обеспечением, которое соответствует спецификации CGI, известны как CGI-скрипты , хотя на самом деле они могли быть написаны на языке, не поддерживающем скрипты, например , C.
Спецификация CGI была быстро принята и продолжает поддерживаться всеми известными пакетами HTTP-серверов, такими как Apache , Microsoft IIS и (с расширением) серверами на базе node.js.
Раннее использование CGI-скриптов было для обработки форм. В начале HTML HTML-формы обычно имели атрибут "action" и кнопку, обозначенную как кнопка "submit". При нажатии кнопки submit указанный в атрибуте "action" URI будет отправлен на сервер с данными из формы, отправленными в виде строки запроса. Если "action" указывает CGI-скрипт, то будет выполнен CGI-скрипт, который в свою очередь сгенерирует HTML-страницу.
Веб-сервер, поддерживающий CGI, можно настроить на интерпретацию URL-адреса , который он служит ссылкой на скрипт CGI. Распространенное соглашение заключается в том, чтобы иметь cgi-bin/
каталог в основании дерева каталогов и обрабатывать все исполняемые файлы в этом каталоге (и ни в каком другом, в целях безопасности) как скрипты CGI. Когда веб-браузер запрашивает URL-адрес, указывающий на файл в каталоге CGI (например, http://example.com/cgi-bin/printenv.pl/with/additional/path?and=a&query=string
), то вместо того, чтобы просто отправить этот файл ( /usr/local/apache/htdocs/cgi-bin/printenv.pl
) веб-браузеру, HTTP-сервер запускает указанный скрипт и передает вывод скрипта веб-браузеру. То есть все, что скрипт отправляет в стандартный вывод , передается веб-клиенту, а не отображается в окне терминала, запустившего веб-сервер. Другое популярное соглашение заключается в использовании расширений имен файлов ; например, если скриптам CGI постоянно присваивается расширение .cgi
, веб-сервер можно настроить на интерпретацию всех таких файлов как скриптов CGI. Хотя это удобно и требуется многими предварительно упакованными скриптами, это открывает сервер для атаки, если удаленный пользователь может загрузить исполняемый код с соответствующим расширением.
Спецификация CGI определяет, как дополнительная информация, переданная с запросом, передается в скрипт. Веб-сервер создает подмножество переменных среды, переданных ему, и добавляет сведения, относящиеся к среде HTTP. Например, если слэш и дополнительные имена каталогов добавляются к URL сразу после имени скрипта (в этом примере /with/additional/path
), то этот путь сохраняется в PATH_INFO
переменной среды до вызова скрипта. Если параметры отправляются в скрипт через запрос HTTP GET (вопросительный знак, добавленный к URL, за которым следуют пары параметр=значение; в этом примере ?and=a&query=string
), то эти параметры сохраняются в QUERY_STRING
переменной среды до вызова скрипта. Тело сообщения HTTP запроса , например параметры формы, отправленные через запрос HTTP POST , передаются на стандартный ввод скрипта . Затем скрипт может считывать эти переменные среды или данные из стандартного ввода и адаптироваться к запросу веб-браузера. [8]
CGI часто используется для обработки входной информации от пользователя и создания соответствующего вывода. Примером программы CGI является реализация вики . Если пользовательский агент запрашивает имя записи, веб-сервер выполняет программу CGI. Программа CGI извлекает исходный код страницы этой записи (если он существует), преобразует его в HTML и печатает результат. Веб-сервер получает вывод от программы CGI и передает его пользовательскому агенту. Затем, если пользовательский агент нажимает кнопку «Изменить страницу», программа CGI заполняет HTML textarea
или другой элемент управления редактированием содержимым страницы. Наконец, если пользовательский агент нажимает кнопку «Опубликовать страницу», программа CGI преобразует обновленный HTML в исходный код страницы этой записи и сохраняет его.
Программы CGI по умолчанию работают в контексте безопасности веб-сервера. Когда они впервые появились, ряд примеров сценариев были предоставлены с эталонными дистрибутивами веб-серверов NCSA, Apache и CERN, чтобы показать, как можно кодировать сценарии оболочки или программы на языке C для использования нового CGI. Одним из таких примеров сценариев была программа CGI под названием PHF, которая реализовала простую телефонную книгу.
Как и ряд других скриптов того времени, этот скрипт использовал функцию: escape_shell_cmd()
. Функция должна была очищать свой аргумент, который поступал из пользовательского ввода, а затем передавать ввод в оболочку Unix для запуска в контексте безопасности веб-сервера. Скрипт некорректно очищал весь ввод и позволял передавать новые строки в оболочку, что фактически позволяло запускать несколько команд. Результаты этих команд затем отображались на веб-сервере. Если контекст безопасности веб-сервера это позволял, злоумышленники могли выполнять вредоносные команды.
Это был первый широко распространенный пример нового типа веб-атаки, называемой инъекцией кода , когда несанкционированные данные от веб-пользователей могли привести к выполнению кода на веб-сервере. Поскольку пример кода был установлен по умолчанию, атаки были широко распространены и привели к ряду рекомендаций по безопасности в начале 1996 года. [9]
Для каждого входящего HTTP-запроса веб-сервер создает новый CGI- процесс для его обработки и уничтожает CGI-процесс после обработки HTTP-запроса. Создание и уничтожение процесса может потреблять больше процессорного времени и ресурсов памяти, чем фактическая работа по генерации выходных данных процесса, особенно когда CGI-программа все еще должна интерпретироваться виртуальной машиной. При большом количестве HTTP-запросов результирующая нагрузка может быстро перегрузить веб-сервер.
Вычислительные затраты, связанные с созданием и уничтожением процесса CGI, можно сократить с помощью следующих методов:
mod_perl
, mod_php
и mod_python
), плагины NSAPI и плагины ISAPI , которые позволяют долговременным процессам приложений обрабатывать более одного запроса и размещаться на веб-сервере.mod_wsgi
(модуль Apache), веб-сервер Gunicorn (между Nginx и скриптами/фреймворками, такими как Django), UWSGI и т. д.Оптимальная конфигурация для любого веб-приложения зависит от деталей, специфичных для приложения, объема трафика и сложности транзакции; эти компромиссы необходимо проанализировать, чтобы определить наилучшую реализацию для данной задачи и бюджета времени. Веб-фреймворки предлагают альтернативу использованию скриптов CGI для взаимодействия с пользовательскими агентами.
{{cite journal}}
: Цитировать журнал требует |journal=
( помощь )