В 1998 году интернет в Кыргызстане был роскошью. Подключение через dial-up провайдеров ElCat или Asiainfo стоило $3-5 за час - при средней зарплате в $30-50 в месяц. Пользователей интернета в стране насчитывалось несколько тысяч, сайтов с доменом .kg - единицы.
Те немногие разработчики, которые создавали сайты для государственных структур, банков или крупных компаний, неизбежно сталкивались с задачей: сделать сайт «живым». Форма обратной связи, гостевая книга, новости из базы данных - всё это требовало CGI. И писали его на Perl.
Первая гостевая книга для бишкекского сайта
#!/usr/bin/perl
# guestbook.pl - гостевая книга, Бишкек, 1998 год
# Сервер: Unix/Linux где-то в Германии или Москве
# Кодировка: windows-1251
use strict;
use warnings;
use CGI;
use POSIX qw(strftime);
my $DATA_FILE = '/home/mysite/data/guestbook.txt';
my $MAX_ENTRIES = 75;
my $cgi = new CGI;
my $action = $cgi->param('action') || 'view';
if ($action eq 'post') {
post_entry($cgi);
} else {
show_entries($cgi);
}
sub post_entry {
my ($q) = @_;
my $name = $q->param('name') || '';
my $email = $q->param('email') || '';
my $message = $q->param('message') || '';
my $from = $q->param('from') || ''; # Откуда (город/страна)
# Базовая очистка
for my $f ($name, $email, $message, $from) {
$f =~ s/[<>&"'\\]//g;
$f =~ s/[\r\n]+/ /g;
}
if (length($name) < 2 || length($message) < 3) {
print_header();
print "<p><font color=red>Введите имя и сообщение!</font></p>\n";
print "<a href='guestbook.pl'>Назад</a>\n";
print_footer();
return;
}
my $ts = strftime('%d.%m.%Y %H:%M', localtime);
my @entries = load_file();
unshift @entries, join('|', $name, $email, $from, $message, $ts);
@entries = @entries[0..$MAX_ENTRIES-1] if @entries > $MAX_ENTRIES;
save_file(\@entries);
print "Content-Type: text/html; charset=windows-1251\n\n";
print "<html><head><meta http-equiv=refresh content='0;url=guestbook.pl'></head>";
print "<body>Записано! <a href=guestbook.pl>Открыть</a></body></html>";
}
sub show_entries {
my ($q) = @_;
print_header();
print "<h2>Написать в гостевую книгу</h2>\n";
print "<form method=POST action=guestbook.pl>\n";
print "<input type=hidden name=action value=post>\n";
print "<table border=0 cellpadding=5>\n";
print "<tr><td>Имя: *</td><td><input name=name size=28></td></tr>\n";
print "<tr><td>E-mail:</td><td><input name=email size=28></td></tr>\n";
print "<tr><td>Откуда:</td><td><input name=from size=28></td></tr>\n";
print "<tr><td valign=top>Текст: *</td>";
print "<td><textarea name=message rows=4 cols=38></textarea></td></tr>\n";
print "<tr><td></td><td><input type=submit value='Отправить'></td></tr>\n";
print "</table></form>\n";
print "<hr>\n<h2>Записи</h2>\n";
my @entries = load_file();
if (!@entries) {
print "<p><i>Записей нет. Будьте первым!</i></p>\n";
}
for my $line (@entries) {
my ($name, $email, $from, $msg, $ts) = split /\|/, $line;
print "<p><b>$name</b>";
print " ($from)" if $from;
print " — <i>$ts</i><br>$msg</p><hr size=1>\n";
}
print_footer();
}
sub load_file {
my @lines;
return @lines unless -f $DATA_FILE;
open my $fh, '<', $DATA_FILE or return @lines;
@lines = grep { /\S/ } <$fh>;
chomp @lines;
close $fh;
return @lines;
}
sub save_file {
my ($lines) = @_;
open my $fh, '>', $DATA_FILE or die "Не могу записать: $!";
print $fh "$_\n" for @$lines;
close $fh;
}
sub print_header {
print "Content-Type: text/html; charset=windows-1251\n\n";
print "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n";
print "<html><head><title>Гостевая книга</title></head>\n";
print "<body bgcolor=#FFFFFF>\n";
print "<h1>Гостевая книга</h1>\n";
}
sub print_footer {
print "<hr><small>Бишкек • 1998 • Perl CGI</small>\n";
print "</body></html>\n";
}
Реалии деплоя в Бишкеке 1998 года
Запустить CGI-скрипт в 1998 году из Бишкека означало несколько практических сложностей:
Хостинг за рубежом. В Кыргызстане практически не было коммерческих хостинг-провайдеров. Сайты размещались в России (Zenon, Demos, Cityline) или Европе (немецкие провайдеры). Это означало:
- Все настройки - через FTP и Telnet из Бишкека
- Задержка (ping до Москвы ~60-80 мс, до Европы ~120-180 мс)
- Техподдержка работала в московском или европейском часовом поясе
# Стандартный workflow деплоя из Бишкека в 1998:
# 1. Написать скрипт в Windows 95/98 (Блокнот или UltraEdit)
# ВАЖНО: сохранить с Unix-переносами строк! Иначе ошибка 500.
# UltraEdit умел конвертировать: File -> Conversions -> DOS to Unix
# 2. Загрузить по FTP в ASCII-режиме (не бинарный!)
# WS_FTP LE - бесплатная FTP-программа, стандарт 1998 года
# Binary режим испортит скрипт: FTP должен конвертировать CRLF -> LF
# 3. Подключиться по Telnet и выставить права
telnet myhost.com
chmod 755 /home/mysite/cgi-bin/guestbook.pl
chmod 777 /home/mysite/data/ # не очень безопасно, но иначе никак
Самая частая ошибка: забыть поставить пустую строку после HTTP-заголовка. Браузер показывал пустую страницу или ошибку сервера. Правило, которое каждый Perl-разработчик знал наизусть:
# ПРАВИЛЬНО - две строки: заголовок + пустая строка
print "Content-Type: text/html\n\n";
# НЕПРАВИЛЬНО - одна строка без пустой строки после
print "Content-Type: text/html\n"; # браузер не поймёт тело ответа
Кодировка и кыргызский язык
В 1998 году добавить кыргызский текст на сайт было практически невозможно технически. Специфические кыргызские буквы (Ң, Ү, Ө, Ё) не входили ни в windows-1251, ни в KOI8-R полностью.
# В Perl 1998 года для кыргызского/русского текста:
print "Content-Type: text/html; charset=windows-1251\n\n";
# Кыргызский текст: либо транслитерация, либо обходились русским
# Буква Ң в windows-1251 отсутствует → писали НГ или избегали
# KOI8-R - вариант для Unix-серверов:
# use Encode;
# my $text = Encode::encode('koi8-r', Encode::decode('cp1251', $win_text));
Полноценный кыргызский язык в вебе появился только с переходом на UTF-8 - примерно к 2006-2008 годам, когда браузеры и серверы наконец стандартизировались на Unicode.
Путь от Perl к PHP в кыргызнете
К 2001-2002 году PHP 4 вытеснил Perl как инструмент веб-разработки и в Кыргызстане. Причины были теми же, что и в остальном русскоязычном интернете:
- Простота деплоя:
.phpфайлы работали как обычные веб-страницы - Русскоязычная документация: php.net/ru, статьи на phpclub.ru
- Хостинг с PHP: российские хостинги добавили поддержку PHP раньше, чем улучшили поддержку Perl CGI
Тем не менее, навыки Perl CGI, полученные в 1998-2000 годах, дали бишкекским разработчикам понимание, которого нельзя получить иначе: как веб-сервер запускает программы, как работает HTTP на уровне заголовков, как хранить состояние без базы данных. Эти знания не устарели - они просто стали невидимы за слоями абстракций современных фреймворков.