На главную

Библиотека Интернет Индустрии I2R.ru

Rambler's Top100

Малобюджетные сайты...

Продвижение веб-сайта...

Контент и авторское право...

Забобрить эту страницу! Забобрить! Блог Библиотека Сайтостроительства на toodoo
  Поиск:   
Рассылки для занятых...»
I2R » Фундамент (dns, ftp, http ..) » CGI (классика, FastCGI, ... )

Что такое CGI?

Сначала раберемся с терминологией. CGI - Commom Gateway Interface это интерфейс, позволяющий веб-серверу по запросу браузера пускать на себе какие-либо программы и результат их работы отдавать браузеру. CGI программа (скрипт) - программа (скрипт), работающая на сервере и обменивающаяся данными с браузером через вышеупомянутый интерфейс. Поскольку не существует жесткой регламентации насчет определений и терминов, то очень часто, говоря CGI, имеют ввиду именно программу (скрипт), а не сам интерфейс.

Если это программа, то она должна иметь любой приемлемый для конкретной операционной системы исполняемый формат. Программы можно писать на чем угодно: C/C++, Pascal, Java, Visual и просто Basic, delphi и т.д.

Если это скрипт (сценарий), то на операционной системе, под которой крутиться веб-сервер должен быть соответствующий интерпретатор сценариев: shell, perl, tcl/tk, command.com и т.д.

Главное, чтобы средство разарботки CGI программы (скрипта) отвечало следующим требованиям: - позволяют читать из стандартного потока ввода (stdin) - получать значения переменных окружения (environment variables) - выводить в стандартный поток вывода (stdout)

Для чего используется CGI:

  • Работа со справочными системами и базами данных.
  • Создание динамических HTML документов и ресурсов (в том числе счетчики, гостевые книги и т.д.)
  • Удаленное администрирование различных систем.
  • Просто работа с различными программами, поскольку HTML интерфейс довольно удобен в использовании, прост в изготовлении и приятно выглядит :)

Механизм работы CGI программ

Как уже было сказано, CGI получает входные данные со стандартного потока ввода stdin или из переменных окружения, а выводит результаты своей работы в стандартный поток вывода stdout. Для тех. кто не знает, что это такое: Стандартный поток ввода (stdin) - отсюда программа (скрипт) по-умолчанию получает входную информацию. Обычно это клавиатура, но его можно переназначить, и программа (скрипт) будет получать входные данные из файла, сокета, выходного потока другой программы.

Переменные окружения (environment variables) - переменные, определенные для системы и сервера, на которой будет выполняться CGI. .

Стандартный поток вывода (stdout) - сюда программа (скрипт) выводит результаты своей работы. Обычно это экран, но его можно переназначит на файл, сокет, входной поток другой программы, принтер и т.д.

Большинство примеров в этом руководстве написано на shell только для того, чтобы упростить изложение материала.

Согласно последним веяниям по соблюдению безопасности не рекомендуется использование shell для написания CGI скриптов.

1.1 Вызов CGI без параметров

Простейший скрипт, выводящий текущую дату:

#!/bin/sh echo Content-type: text/html echo echo "<h2>Today is " date echo "</h2>" В HTML документе ссылка на него описывется вот таким образом <a href="/cgi-bin/examples/today.cgi">

ВАЖНОЕ ЗАМЕЧАНИЕ Основной ошибкой, которую совершают почти все, кто начинает писать CGI программы или скрипты, заключается в том, что они забывают вставить указатель на тип выводимого результата - заголовок выводимого документа. Это вторая и третья строчки в примере.

echo Content-type: text/html echo где Content-type: - тип выводимого документа (text/html, image/gif, image/jpeg и т.д.).
Пустая строка в выводе говорит о том, что заголовок кончился и далее следует собственно сам документ.

1.2 Передача параметров CGI скрипту или программе

Передача параметров осуществляется двумя основными методами: GET и POST. У каждого из них свои достоинства и недостатки.

При использовании GET параметры добавляются к запрашиваемому URL и его можно вызывать таким образом:

http://какой-то_хост/cgi-bin/какой-то_скрипт?параметры что позволяет делать на такой скрипт ссылки в HTML документах. А на сервере переданные параметры присваиваются переменной QUERY_STRING.

Текст самого скрипта:

#!/bin/sh echo Content-type: text/html echo echo "<h2>Вы посылали вот это:</h2>" echo "<b>" set | grep QUERY_STRING echo "</b><br><hr>" echo "<b>Environment</b><br><xmp>" set echo "" и как он вызывался из этого документа: <a href="/cgi-bin/examples/link.cgi?some_parameters"> Пример работы (ткните тут) </a>

Но применение метода GET для передачи параметров, содержащих конфиденциальную информацию недопустимо, т.к. в данном случае вся эта информация передается открыто.

Метод POST позволяет обеспечить конфиденциальность при передаче параметров скрипту. Но он передает параметры на стандартный поток ввода и для этого приходится использовать формы. Сервер не посылает скрипту EOF в конце передачи. Вместо этого вам придется использовать пременную окружения CONTENT_LENGTH, чтобы определить какой объем данных вам надо считать из stdin.

Пишем счетчик

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

Эта глава руководства будет скорее полезна тем, кому интересен именно механизм работы счетчиков, поскольку все прилагаемые примеры особыми "наворотами" по части настроек, администрения, и т.п. не обладают. Более "навороченые", готовые к эксплуатации счетчики ищите на Altavista, Yahoo и др. поисковых серверах. Или спрашивайте в соответствующих конференциях новостей (relcom.www.users, relcom.www.support; в фидошных эхах ru.internet.*).

2.1 Типы счетчиков

По механизму работы счетчики условно можно разделить на два типа:
  1. CGI скрипты работающие как Server Side Include
  2. CGI скрипты не использующие Server Side Include
Server Side Include (SSI) - тип HTML комментария , который указывает Web серверу, что в месте вызова необходимо подставить динамически сгенерированные данные. Основной формат вызова SSI в теле HTML документа выглядит следующим образом:

< !--#command tag="value"...--> 

где #command - любая из многочисленных команд понимаемых Web сервером. В данном случае наибольший интерес представляет команда #exec, которая позволяет выполнять программы и подставлять результаты их работы. Анализируемые Web сервером HTML документы называются server-parsed документами.

2.2 Cчетчик посещений работающий как SSI

Алгоритм работы:

  1. Сервер получает от браузера запрос на HTML документ.
  2. Сервер просматривает документ на наличие вызова SSI.
  3. Если такие вызовы обнаружены, то на их место подставляется результат. В случае команды #exec - результат работы программы, указанной в "value".
  4. Сформированный HTML документ возвращается браузеру.

Необходимые настройки сервера (на примере сервера Apache):

  1. В файле srm.conf прописать (если там еще не прописано): AddType text/html .shtml AddHandler server-parsed .shtml Эти директивы говорят серверу, что файлы с раширением .shtml являются server-parsed документами.
  2. В файле access.conf на директорию, где будут лежать server-parsed документы, в Options добавить опцию Includes.
  3. Файлам, содержащим вызовы SSI присвоить расширение .shtml (см. п. 1)
Продемонстрируем работу счетчика на примере скрипта counter, найденного в Интернете на http://www.webtools.org/. Он написан на столь популярном ныне Perl'е.

Вот тут будем считать : < !--#exec cgi="/cgi-bin/counter"-->
(нажимайте Reload пока не надоест)

Этот счетчик текстовый, т.е. скрипт возвращает просто текст, который и показывается. Аналогичным образом можно выводить и картинки. Для этого нужно, чтоб вместо текстовых цифр выводились тэги img src="картинка_с_соответсвующей_цифрой". Пытливый читатель легко догадается, что количество тегов img src... равно количеству цифр в значении возвращаемом счетчиком.

Вызов этого счетчика в теле документа осуществляется командой:

 <  !--#exec cgi="/cgi-bin/counter"--> 

2.3 Счетчик не использующий SSI

Более простым с точки зрения пользователя, но более сложным в программировании является счетчик не использующий SSI. Механизм работы такого счетчика представляет из себя следующее:

  • в теле HTML документа указывается: <img src="/cgi-bin/examples/counter.cgi"> т.е. запрашиваемая картинка не является статической, а динамически генерируется CGI скриптом.
  • сервер, получив запрос на картинку, запускает скрипт, указанный в src тэга img.
  • скрипт, увеличивает значение счетчика на единицу, генерирует картинку со значением счетчика и возвращает ее браузеру.

Поскольку данный тип счетчиков является самым популярным в Интернете, то алгоритм его работы рассмотрим более подробно.

Скрипт (counter.cgi), который вызывается в теле HTML документа тэгом img src="...counter.cgi" написан на shell и имеет следующий исходный текст (номера строк добавлены только для упрощения объяснения):

1: #!/bin/sh 2: now=`date -u` 3: echo "Content-type: image/gif;" 4: echo "Expires: $now" 5: echo 6: counter|showdigits

Что делает этот скрипт (построковое описание):
1 - Заголовок самого скрипта. Он указывает на командный интерпретатор, который будет его выполнять.

2 - Определяем переменную now, которая содержит время запуска скрипта (время создания картинки). Ключик '-u' говорит, что, дата/время создания выводяться в GMT. Зачем это надо будет описано ниже.

3 - Начинаем формировать заголовок ответа сервера. Указываем тип возвращаемых данных: image/gif

4 - Поскольку это счетчик, то необходимо обеспечить, чтобы картика с его показаниями не кэшировалась (а то какой он после этого счетчик:). Для этого указываем, что полученая браузером картинка должна немедленно заэкспайриться. Вот тут то мы и используем переменную now, определенную в строке номер 2. Употребление Expires в таком виде соответствует стандарту на HTTP протокол версии 1.1. Но при использовании Expires равным дате создания документа могут возникать забавные глюки, если часы на клиенте отстают от часов сервера на несколько минут. Возникает дилемма - по стандарту положено так, а получается не то что надо. Что делать? В предыдущей версии протокола (HTTP 1.0) Expires можно было выставлять равным 0, а RFC2068 гласит, что клиенты и кэши работающие по HTTP 1.1 должны поддерживать старый вариант использования Expires (Expires: 0). Так шта, дорогие россияне, решайте сами.

5 - Конец заголовка ответа - возвращаем пустую строку.

6 - Используя две программы (counter и showdigits) генерим саму картинку.

Программы counter и showdigits написаны на Си с использованием библиотеки для работы с GIF файлами - libgd. Без нее программы компилироваться не будут. Последнюю версию библиотеки всегда можно получить на http://www.boutell.com/gd/.

Что делают эти программы:

  • counter - читает из файла counter.rc число, представляющее из себя предыдущее значение счетчика, прибавляет к нему единичку и пишет обратно. Если не указан путь к файлам - картинкам с цифрами и маска этих файлов,то береться дефолтовая, которая определна в теле программы. После этого она вычисленное значение счетчика и пути к картинкам выводяться на stdout, чем формируется коммандная строка для showdigits.
  • showdigits - эта программа, собственно, и формирует картинку с текущим показанием счетчика. Для этого используется набор готовых картинок с цифрами (gif формат, все картинки одинакового размера) и полученные на stdin от counter данные. По пути, маске и числу беруться нужные картинки и из них собирается один гиф. После чего он отправляется прямиком на ... stdout! А далее сервер перенапрявляет этот поток браузеру и он (браузер) показывает его как картинку, поскольку в заголовке ответа указано, что это гиф.
Вся суть здесь вот в чем: - Сервер передает браузеру поток данных. - Браузеру абсолютно все равно, где и как сервер взял передаваемый ему поток данных (статический ли это, или динамически сгенеренный; обычный файл или результат жизнедеятельности скрипта), главное, чтоб браузер знал как его правильно интерпретировать. Для этого служит заголовок, который в данном примере был сгенерирован скриптом counter.cgi, а именно в 3-5 строках (см. выше). Причем, в случае статических файлов сервер сам генерирует этот заголовок, исходя из собственных настроек, а в случае с cgi это должен делать сам скрипт.

Server side includes

Ежу понятно, что статические HTML документы - это хорошо, а динамически создаваемые - еще лучше.:) Так вот, в этой главе мы поговорим о динамическом создании документов с использованием Server Side Includes. Сразу отметим, что возможность использования SSI - это возможность каждого конкретного сервера. Некоторые сервера не поддерживают SSI, а у тех, которые имеют такую возможность, могут различаться форматы и наборы команд. Так что, читайте инструкцию по эксплуатации вашего Web-сервера. Все примеры в этой главе приведены для сервера Apache.

3.1 Что такое SSI

Как уже было сказано впредыдущей главе, Server Side Include (SSI) директива Web-сервера, позволяющая серверу подставлять на место вызова какие-либо данные. В HTML документе вызов SSI выглядит как комментарий формата:

< !--#command tag="value"...--> 

где #command - любая из SSI директив понимаемых Web сервером, а "value" - ее параметры.

Подставляемые данные могут быть статическими и динамически генерируемыми. Статические данные уже готовые, записанные в виде файлов, фрагменты текста или HTML. Такие данные удобно применять в случае, когда в различных HTML документах содержаться повторяющиеся фрагменты. Динамически генерируемые данные результаты работы каких-либо CGI скриптов или команд операционной системы, на которой работает конкретный Web-сервер. Использование этого типа данных предоставляет Web-девелоперу огромные возможности. Но, как гласит дебильная российско-буржуйская реклама, - "Не забывай про Орбит без сахара!". То бишь, ПОМНИ О МЕРАХ ПО СОБЛЮДЕНИЮ БЕЗОПАСНОСТИ ДОСТУПА К ИНФОРМАЦИИ! Неправильное использование SSI может привести к появлению возможности несанкционированного доступа к информации и, соответственно, к различным тяжким последствиям. Чтобы уберечься от этого - читайте необходимую литературу. Например, от W3C (master site: http://www.w3.org/Security/Faq/) или одно из его многочисленных. В том числе и на русском: http://private.peterlink.ru/www-security-faq/.

3.2 Основные SSI директивы

config управляет различными аспектами анализа (parsing) документа. Атрибуты: errmsg сообщение об ошибке, возвращаемое клиенту, если при анализе документа произошел какой-либо сбой. sizefmt устанавливает формат вывода размера файла (байты, килобайты, мегабайты). timefmt устанавливает формат вывода даты/времени. echo печатает значение одной из нижеописаных переменных окружения. Атрибуты: var имя печатаемой переменной exec выполняет указанную команду или CGI скрипт. Атрибуты: cgi указывается (%-кодированый) URL-относительный путь к CGI скрипту. Если путь не начинается с (/), считается, что путь указан относительно текущего документа.

CGI скрипту передаются так же значения переменных PATH_INFO и QUERY_STRING оригинального запроса клиента.

cmd сервер выполняет указанную строку, используя командный интерпретатор операционной системы. fsize печатает размер указанного файла с учетом sizefmt. Атрибуты: file указывается путь к файлу относительно текущей директории содержащей анализируемый файл. virtual указывается (%-кодированый) URL-относительный путь к файлу. Если путь не начинается с (/), считается, что путь указан относительно текущего документа. flastmod печатает дату/время последнего изменения указанного файла с учетом timefmt. Атрибуты такие же как у команды fsize. include вставляет текст другого документа или файла в анализируемый документ. Очень полезна при повторяющихся фрагментах в разных документах. Атрибуты: file указывается путь к файлу только относительно текущей директории содержащей анализируемый файл. virtual указывается (%-кодированый) URL-относительный путь к файлу. Если путь не начинается с (/), считается, что путь указан относительно текущего документа. В Apache включаемые таким образом файлы могут быть вложенными. printenv печатает список всех существующих переменных и их значения. Атрибутов нет. Пример:
< !--#printenv --> 
set устанавливает значение переменной. Атрибуты: var указывается имя устанавливаемой переменной. value указывается значение устанавливаемой переменной. Пример:
< !--#set var="variable_1" value="some_value_of_variable_1" -->  

3.3 SSI переменные окружения

DOCUMENT_NAME - имя файла Описание в теле документа:
< !--#echo   var="DOCUMENT_NAME" --> 
Результат использования:< !--#echo var="DOCUMENT_NAME" -->

DOCUMENT_URI - виртуальный путь к файлу Описание в теле документа:
< !--#echo   var="DOCUMENT_URI" --> 
Результат использования:< !--#echo var="DOCUMENT_URI" -->

QUERY_STRING_UNESCAPED - раскодированя query string, причем все метасимволы shell предваряются "\" Описание в теле документа:
< !--#echo var="QUERY_STRING_UNESCAPED" --> 
Результат использования:

DATE_LOCAL - текущая дата и время (местное) Описание в теле документа:
< !--#echo   var="DATE_LOCAL" --> 
Результат использования:< !--#echo var="DATE_LOCAL" -->

DATE_GMT - текущая дата и время (GMT) Описание в теле документа:
< !--#echo   var="DATE_GMT" --> 
Результат использования:< !--#echo var="DATE_GMT" -->

LAST_MODIFIED - дата и время последнего изменения файла Описание в теле документа:
<  !--#echo   var="LAST_MODIFIED" --> 
Результат использования:< !--#echo var="LAST_MODIFIED" -->

3.4 Настройка сервера

Для того, чтобы серевер знал, в каком месте в документе подставлять данные, он должен этот документ проанализировать. Анализируемые сервером документы называются server-parsed документами.

В первую очередь надо дать понять серверу, какие документы он должен анализировать. Для этого в файл конигурации (для Apache старых версий и NCSA web-серверов это файл srm.conf, а для новых версий Apache, например 1.3.4 - httpd.conf), нужно добавить следующие параметры: Сервер Apache:

AddType text/html .shtml<BR>AddHandler server-parsed .shtml

Сервер NCSA:

AddType text/x-server-parsed-html .shtml Указанные параметры говорят о том, что все файлы с расширением .shtml являются server-parsed, и перед тем как "отдать" этот документ клиенту сервер должен их проанализировать.

Зачем указывать отдельное расширение для server-parsed документов?,- спросит пытливый читатель. Отвечаем. Конечно, никто не мешает добавить в файл конфигурации строку

AddType text/x-server-parsed-html .html Однако это приведет к тому, что сервер будет анализировать все документы с расширением.html, даже если в них нет вызова SSI, загрузка системы увеличиться, а производительность сервера снизится.

Не следует забывать и о том, что бесполезно включать вызов SSI в CGI программы, поскольку их вывод сервером не анализируется.

Для получения более детальной информации по конфигурированию вашего сервера на предмет использования SSI читайте документайию на ваш сервер.

Приложения

Приложение 1. Переменные окружения сервера

Ниже приведен список основных переменных окружения сервера с краткими описанием назначения.В данном случае сервер Apache 1.2.5 с модулем PHP/FI-2.0.1. Для других веб-серверов (MS IIS, Netscape, NCSA httpd, и т.д.) переменные могут отличаться.

REMOTE_HOST - имя хоста приконнектившегося к серверу. В случае работы через прокси - имя прокси.
Пример: REMOTE_HOST=lom.pvrr.ru

REMOTE_ADDR - IP адрес хоста приконнектившегося к серверу. В случае работы через прокси - IP адрес прокси.
Пример: REMOTE_ADDR=194.87.186.11

REMOTE_PORT - номер порта клиента.
Пример: REMOTE_PORT=3381

HTTP_USER_AGENT - имя/номер версии/и т.д. клиента (браузера). Использование этой переменной иногда приводит в бешенство отдельных пользователей Интернет.:) Но на самом деле очень полезная вещь. Например для автоопределения русских кодировок.
Пример:HTTP_USER_AGENT=Mozilla/4.07 [en] (X11; I; FreeBSD 2.2.6-RELEASE i386)

HTTP_ACCEPT - типы данных, помимо text/html, воспринимаемые клиентом (браузером)
Пример: HTTP_ACCEPT=image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*

HTTP_ACCEPT_CHARSET - какие чарсеты понимает клиент (браузер).
Пример: HTTP_ACCEPT_CHARSET=iso-8859-1,*,utf-8

HTTP_ACCEPT_LANGUAGE - какие языки воспринимвает клиент (браузер).
Пример: HTTP_ACCEPT_LANGUAGE=nl,nl-BE,ru

* * *

SERVER_NAME - имя сервера соответствующее записи IN A в DNS, или значение переменной ServerName (или похожей) в конфиге сервера.
Пример: SERVER_NAME=arche.pvrr.ru

HTTP_HOST - имя сервера или виртуального хоста, к которому обращается клиент. Значение HTTP_HOST может быть равным значению SERVER_NAME.
Пример: HTTP_HOST=www.pvrr.ru

SERVER_SOFTWARE - какое ПО используется в качестве сервера.
Пример: SERVER_SOFTWARE=Apache/1.2.5 PHP/FI-2.0.1

DOCUMENT_ROOT - путь к "корню" веб-сервера от "корня" файловой системы копьютера, на котором он работает.
Пример: DOCUMENT_ROOT=/usr/local/www/html

HTTP_CONNECTION - тип соединения.
Пример: HTTP_CONNECTION=keep-alive

SERVER_PROTOCOL - протокол, используемый для обмена данными с конкретным клиентом.
Пример: SERVER_PROTOCOL=HTTP/1.0

REQUEST_URI - имя запрашиваемого ресурса/документа, включающее в себя путь от корня веб-сервера. При обращении к корню сервера или каталогу этой переменной присваивается имя каталога или "/" в случае корня сервера.
Пример: REQUEST_URI=/cgi-bin/tralala/script.cgi

DOCUMENT_URI - имя запрашиваемого ресурса/документа, включающее в себя путь от корня веб-сервера. Обычно инициализируется при вызове SSI. В отличие от REQUEST_URI эта переменная, в случае обращения к каталогу или корню сервера получает значение содержащее и имя файла, являющегося Directory Index'ом этого каталога.
Пример: DOCUMENT_URI=/tralala/index.shtml

HTTP_REFERER - полный URL документа, по ссылке с которого вы попали на этот сервер. Эту переменную можно использовать при написании счетчиков.
Пример: HTTP_REFERER=http://lom.pvrr.ru/java/cgi/cgi_1.html

GATEWAY_INTERFACE - название/версия интерфейса, через который сервер работает со скриптом.
Пример: GATEWAY_INTERFACE=CGI/1.1

SCRIPT_FILENAME - имя скрипта, содержащее полный путь от "корня" файловой системы.
Пример:SCRIPT_FILENAME=/usr/local/www/cgi-bin/tralala/script.cgi

SCRIPT_NAME- имя скрипта, содержащее путь от "корня" веб-сервера.
Пример: SCRIPT_NAME=/cgi-bin/tralala/script.cgi

REQUEST_METHOD - метод используемый клиентом для передачи данных серверу. Бывают GET, HEAD, POST, PUT.
Пример: REQUEST_METHOD=GET

QUERY_STRING - этой переменной значение присваивается при передаче данных серверу методом GET
Пример: QUERY_STRING=button=on

CONTENT_LENGTH - этой переменной присваивается значение, равное количеству байт, переданных браузером серверу при использовании метода POST.
Пример: CONTENT_LENGTH=9

REMOTE_USER - имя пользователя. Передается только если аутентифицируется доступ к CGI скрипту.

PATH_INFO - дополнительная информация о пути, которую передал клиент. То есть скрипт может получать некоторые параметры, содержащие информауцию о некотором "пути" к некоторым данным (например к файлу конфигурации, необходимому для обработки запроса отименно этого клиента). Этот путь "виртуальный" - т.е от "корня веб-сервера". Остальные данные можно передавать как обычно - методом GET или POST.
Пример: PATH_INFO=/some/path

PATH_TRANSLATED - то же , что и PATH_INFO, только путь физический - "от корня файловой системы"

REMOTE_IDENT - Если HTTP сервер поддерживает идентификацию согласно RFC 931, то этой переменной присваивается имя пользователя получаемое от сервера.

SERVER_ADMIN - e-mail администратора веб-сервера.
Пример: SERVER_ADMIN=webmaster@www.pvrr.ru

SERVER_PORT - порт, который "слушает" веб-сервер.
Пример: SERVER_PORT=80

* * *

HTTP_X_FORWARDED_FOR - в случае работы через прокси - IP адрес клиента, работаеющего через прокси.
Пример: HTTP_X_FORWARDED_FOR=194.87.186.11

HTTP_VIA - имя, номер порта, версия ПО прокси-сервера.
Пример: HTTP_VIA=1.0 proxy1.pvrr.ru:8080 (Squid/2.1.PATCH1)

HTTP_CACHE_CONTROL - что-то связанное с возрастом документа в кэше прокси сервера:) Врать не буду - не знаю:)
Пример: HTTP_CACHE_CONTROL=max-age=259200

Vladimir Schuckovsky

Другие разделы
Почта (e-mail)
CGI
Архивы (ftp...)
HTTP
Новое в разделе
DNS
I2R-Журналы
I2R Business
I2R Web Creation
I2R Computer
рассылки библиотеки +
И2Р Программы
Всё о Windows
Программирование
Софт
Мир Linux
Галерея Попова
Каталог I2R
Партнеры
Amicus Studio
NunDesign
Горящие путевки, идеи путешествийMegaTIS.Ru

2000-2008 г.   
Все авторские права соблюдены.
Rambler's Top100