Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

CGI-программирование с самого начала


Информационный Канал Subscribe.Ru

CGI-программирование с самого начала


От автора

Уважаемые подписчики!

Приношу Вам свои извинения за то, что эта рассылка не выходила уже больше года. Виной тому - не лень автора, а объективные и неприятные непредвиденные обстоятельства, которые у меня появились уже после того, как я начал выпускать эту рассылку. В результате у меня не было ни времени, ни моральных сил. Сейчас обстоятельства вновь изменились, выпуск рассылки продолжился и, я надеюсь, надолго. Искренне желаю здоровья Вам и Вашим близким.

Для тех из Вас, для которых этот выпуск - первый, рекомендую прочитать предыдущие выпуски рассылки в архиве рассылки на subscribe.ru - он находится здесь.

Особенности вывода скриптом "бинарного" содержимого

В предыдущем выпуске мы рассматривали вывод CGI-скриптом результата своей работы. Однако CGI-скрипты могут выводить не только "текстовое" содержимое (в формате HTML или простого текста), но любое другое содержимое, которое может быть распознано браузером - картинки, скачиваемые файлы и т.п. (При этом поле ответа Content-Type должно корректно отражать тип выводимого содержимого).

Однако здесь есть один нюанс - ввод и вывод файлов в языке perl может производиться в двух режимах - текстовом и бинарном. А потоки стандартного ввода, стандартного вывода и ошибок - это ведь тоже файлы! По умолчанию файл "работает" в текстовом (ASCII) режиме.

В бинарном режиме данные передаются "как есть" - байт в байт. В текстовом режиме данные передаются с учетом того, что это текст.

Казалось бы, какая разница, что выводить - текст или что-то еще? Ведь, в конце концов, текст - это ведь тоже последовательность байт? Зачем для него нужен какой-то специальный режим?

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

Практически во всех операционных системах есть понятие простого (или "плоского") текста. Это текст, который может в общем случае содержать только текстовые символы и переводы строк (ну, и символ конца текста). Это тот самый формат, в котором система хранит, в частности, различные текстовые конфигурационные файлы. В таком же виде браузеры принимают содержимое в текстовых форматах: HTML, text, css и т.п.

В принципе, одного режима передачи, а именно бинарного, было бы вполне достаточно, если бы ни одна неприятная "историческая" особенность: форматы простого текста различаются в различных операционных системах! В частности, в системах DOS и Windows перевод строки представлен двумя символами - "возврат каретки" (код 13) и собственно "перевод строки" (код 10). А в UNIX и UNIX-подобных системах - одним символом - "перевод строки".

Соответственно, если перенести "байт в байт" текст с UNIX на Windows машину или наоборот, текст нормально читаться не будет ("Блокнот", например, покажет весь UNIX-воский текст в одну строку).

Еще хуже обстоит дело с теми файлами, которые читаются не только людьми, но и программами - если Вы, например, "закачаете" на сервер своего хостинга perl-скрипт по FTP в Binary-режиме, то интерпретатор perl не сможет с ним работать (на этом, кстати, "накалываются" многие начинающие CGI-программисты - я в свое время тоже испытал полное недоумение :-) ).

В принципе (теоретически, так сказать) можно было бы использовать для записи-чтения текстов и бинарный режим, поскольку он универсальный и с его помощью можно прочитать и записать без искажений что угодно. Но поскольку порты интерпретатора perl существуют сейчас практически для всех используемых платформ, то программа (скрипт) может работать под разными системами. Веб-сервера работают на разных платформах - в основном это системы семейства UNIX, но есть и NT, и NetWare, и другие. Как же скрипт может определить, под какой системой он работает, и какие переводы строк в данном случае ему формировать?

Поэтому придумали специальный режим для передачи текстов. При передаче файлов в текстовом (ASCII) режиме переводы строк заменяются таким образом, чтобы файл в данной системе читался корректно. При этом программам, читающим или записывающим текст (неважно, под какой системой они работают) в качестве перевода строки нужно использовать его UNIX-вариант (код 10, escape-символ '\n').

В качестве примера рассмотрим очень простую программу:



#!/usr/bin/perl
open F,">proba.txt";
print F "\n\n";
close F;

Эта программа создает файл "proba.txt" в той же директории, где она сама находится, и записывает в него два перевода строки.

При этом, если она запущена на UNIX-машине, она создаст двухбайтный файл - с двумя кодами "перевод строки" (шестнадцатеричное 0A 0A). Если же ее запустить на Windows -машине, она создаст четырехбайтный файл (шестнадцатеричное 0D 0A 0D 0A). Т.е. в каждой системе получится корректный текстовый файл в стандарте данной системы.

При чтении - наоборот: переводы строк данной системы заменяются на '\n'.

Вернемся теперь к нашим баранам, вернее, к выводу скриптом бинарного содержимого.

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

binmode FILE;

где FILE - это файловый указатель (дескриптор).

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

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

Этот пример читает из файла "picture.gif" картинку и передает ее броузеру:


#!/usr/bin/perl
open PIC,"<picture.gif";
binmode PIC;
sysread PIC, $picture, -s PIC;
close PIC;

print "Content-Type: image/gif\n\n";
binmode STDOUT;
print $picture;

Вот вроде бы и все, что касается вывода результатов работы CGI-скрипта. В следующем выпуске мы рассмотрим "обратную сторону" ввода-вывода, как скрипты могут получать информацию - параметры, условия запуска, информацию о клиенте и.т.д.


Успехов!
Андрей
http://www.angel07.webservis.ru/ - AC-Power: все про Интернет и для него
http://www.cgi-scripts.info/ - CGI-Scripts.Info: все о CGI-скриптах

Subscribe.Ru
Поддержка подписчиков
Другие рассылки этой тематики
Другие рассылки этого автора
Подписан адрес:
Код этой рассылки: inet.webbuild.perlcgi
Отписаться
Вспомнить пароль

В избранное