ALT Linux Team development discussions
 help / color / mirror / Atom feed
From: Aleksey Novodvorsky <aen@altlinux.ru>
To: devel@altlinux.ru
Subject: [devel] [Fwd: Рассказ об установке ALTLinux]
Date: Fri, 04 Jan 2002 22:57:39 +0300
Message-ID: <3C360933.3DEA49A@altlinux.ru> (raw)

[-- Attachment #1: Type: text/plain, Size: 112 bytes --]

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

Rgrds, Алексей

[-- Attachment #2: Type: message/rfc822, Size: 29630 bytes --]

From: Andrey Orlov <cray@iig.ru>
To: aen@altlinux.ru
Subject: Рассказ об установке ALTLinux
Date: Fri, 4 Jan 2002 23:40:03 +0300
Message-ID: <02010423400303.16854@fire.neural.ru>



[-- Attachment #2.1.1: Type: text/plain, Size: 18100 bytes --]

Hi!

Похоже, предыдущее письмо затерялось.

-----------------------------------------------------------------------
$Id: ОтчетОбУстановкеALT.txt,v 1.8 2001/12/21 02:03:06 cray Exp $'
-----------------------------------------------------------------------
 =========
 Зависимости
 =========

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


 -- MySQL потребовал установки PerlDB в обязательном порядка. Хотя обратная
    ситуация была бы не лучше. Разумно ли существование такой зависимости:
    MySQL не всегда используют вместе с Perl, может быть стоит ее подавить?

 -- Никому в голову не придет ставить линух без пакета filesystem, но у нас
    такое получилось: зависимости это допустили. Соотв., последующие пакеты,
    используеющие каталог, например, /var/tmp, отказались ставится без
    видимых причин: т.к. такой зависимости в них не было. Если нам не изменяет
    память, это были все пакеты perl*;


 ========
 Добавленные пакеты
 ========

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

   perl-HTML-Template-2.4-iig1.src.rpm  - это знаменитый HTML::Template;

   perl-MIME-Base64-2.12-iig1.src.rpm - Кодировщик/декодировщик Base64;

   perl-MIME-Lite-2.117-iig1.src.rpm - Посылалка писем;     

   perl-MIME-Types-0.06-iig1.src.rpm - Определение MIME-типа по расширению;

 Мы собрали по вашим примерам для них rpm'ы, и, возможно это неплохо
 получилось. Хотя мы вряд ли возьмемся их поддерживать, т.к. с перлом
 работаем все меньше и меньше, но то что собрали можем передать вам:
 выложить на ftp или закатать на болванку - как вам будет удобнее.

 Пришлось добавить группу пакетов для питона & Zope, про Zope 
 подробно скажу ниже, про питон вот:

    MySQL-python-0.9.0-1.i686.rpm - сбсно, коннектор к MySQL. Питон для нас
	основной язык разработки, да и среда, с нашей точки зрения, должна
	быть целостной, навено разумно включить пакет в дистрибутив.  Наша
	поддержка возможна, если она актуальна. Кстати, коннектор к
	PostgreSQL, кажется у вас есть.

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

 Что забавно, такие утилиты существуют. Часть из них мы перетащили под 
 Alt:

  ipaudit-0.92-0.src.rpm - счетчик & классификатор пролетающих мимо пакетов.
	Эксплуатация показала, что это весьиа качестенная реализация.

  ntop-1.3.2-5alt1.src.rpm - это из редхетовского дистрибъюшена. Красиво,
	реалтаймово, но бесполезно и глючно: подробных логов не ведет, часто
	падает, в общем, при разговорах с начальством штука бесполезная.

 Аналогичная мелочь:

  atsar_linux-1.5-1IIG.src.rpm - сбор статистики использования системы.

 =========
 Вопросы
 =========

 У меня возник ряд вопросов относительно конфигурации пакетов по умолчанию:

 bind - удивил сконфигуренный по умолчанию сhaosnet. Чесгря, я думал, что это
	дела давно минувших дней, времен Lisp-машин и институтских сетей.

 чрутизация - не то, что бы я возражал.... Но были ли какие-то реальные
	эксплойты на mysql & bind, и стоит ли вообще-то овчинка, хм,
	выделки? Хотя удивило то, что чрутизация заняла столь мало места.


 =========
 Zope
 =========

 С Zope была чумовая история: несмотря на ваши заверения, у нас есть
 серъезные опасения, что ситуация не изменилась, т.к. с Zope было два уровня
 ошибок: скорее всего вы заметили первый, но если вы не эксплуатируете Z, то
 вряд ли заметили второй.

 Первый уровень связан с тем, что несколько фрагментов Zope в него в вашей
 версии не вошли: запускаться он отказался напроч. Скорее всего это было
 исправлено, но вот краткое переичисление пропущенных файлов:

 /usr/share/zope/lib/python/Products/PluginIndexes/TextIndex/Splitter
 /usr/share/zope/lib/python/BTrees
 /usr/share/zope/lib/python/RestrictedPython

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

 А теперь второй уровень, который, вполне возможно, не исправлен до сих пор:
 Мы радостно все это дело запустили, перебросили в новый Zope наш тогдашний
 пакет и начали с ним работать. Через три дня эксплуатации Zope благополучно
 умер. Вместе с ZODB. Вам будет понятно удивление, если вспомнить, что за
 предыдущий год не было ни одного сбоя. Мы восстановили данные с бакапа,
 начали разбираться и вот что выяснилось: Zope из ваших пакетов через
 два-три дня умирает. Вместе с базой - сам формат базы оказался
 несовместимым с нормальной версией. Против этого не помогла ни пересборка,
 ни внимательное изучение вашего пакета: после трех дней попыток исправить
 ваш пакет мы взяли Z c www.zope.org и пересобрали его оттуда, после чего
 баги прошли.

 Ситуацию усугубляло еще и то, что сама планировка инсталляции Zope была в
 принципе не пригодна для его серьезной эксплуатации. Я понимаю, что она
 следует рекомендациям DC, но мы с нашим опытом работы с Z привыкли к более
 серъезным настройкам, равно как к обязательному наличию ряда необязательныъ
 пакетов ;).

 История закончилась тем, что мы полностью отказались от использования
 результатов проекта "Zope RPM", т.к.  во-1-ых его результы не
 жизнеспособны, а во-2-ых структура пакета, с нашей точки зрения, очень
 слабо учитывает реалии использования Z на полукоммерческом хостинге.  Мы
 собрали свой пакет, разумеется, из DC'шных (www.zope.org) исходников.

 Основные отличия:

 1. Мы ориентируемся на то, что на хосте запущено несколько Z-серверов. Это
 крайне удобно с точки зрения разработки, эксплуатации и хостинга десятка
 проектов. Как правило, у нас запущено два Z-сервера, коммерческий и
 тестовый, иногда доходит до трех.

 2. Мы добавили пакеты в питон и в Z: часть наши собственные, в т.ч.
 кирилический багфикс, часть - чужие. Вот их список:

    ZProducts-ZMySQLDA-2.7.0-1.src.rpm	- коннектор к MySQL, очевидно, стоит
	добавить еще и коннектор к PostgreSQL: нам он не нужен, но с точки
	зрения целостности...

    ZProducts-mysqlUserFolder-0.6.0-1.src.rpm - эта версия основательно
	пропатчена нами.  Специально для MSIE & Russia. Видимо, мы будем
	связываться с авторами на предмет включения наших патчей.

    Zope-2.4.2-iig1.src.rpm - это сам Z: о его структуре лучше грить
    отдельно.

    CrayFIX, AqGuard, FloodGuard, CrazyGuard, SemanticGuard, RequestDecoder -
	это все сейчас в стадии разработки. Видимо, будет выложено на сайтах
	www.neural.ru & www.iig.ru для свободного даунлоада в течении
	недели-двух. Вот цитата из нашего внутреннего документа поддержки
	технологии разработки:

	CrayFIX - русификация ZServer'а

	Установка пакета вызывает добавление в заголовок ContentType
	кодировки, без которой ряд грязно реализованных браузеров, таких как
	MS Internet Explorer, не способны работать с сайтом. Обнаружение в
	конетексте специальных объектов, таких как libIIGFS и RequestDecoder
	вызывает добавление ряда полезных функций в менеджерский интерфейс
	Zope.

	RequestDecoder - автоматическое декодирование запросов

	Установка пакета позволяет создать объект, осуществляющий
	автоматическое распознавание кодировки входящих запросов и
	перекодирование их в кодировку сервера. Без его установки ряд версий
	грязно реализованных браузеров, таких как MS Internet Explorer, не
	способны правильно работать с сайтом.

	AqGuard & CrazyGuard - защита от сумашедших роботов

	Особенности объектной модели Zope могут приводить к неограниченной
	рекурсии индексирующих роботов, превращая их нормальные действия в
	DoS-атаку против сайта. Установка экземпляра объекта AqGuard
	позволяет ограничить рекурсию и заблокировать запрос при обнаружении
	повторного обращения к контейнеру в рамках запроса, а объекта
	CrazyGuard - обнаружить факт индексации сайта сумашедшим роботом и
	сгенерировать отказ в доступе или заблокировать обработку запроса
	при повышенной нагрузке на сайт в этот момент.

	FloodGuard - защита от флуда

	Объект FloodGuard дает общее решение проблемы флуда & спамминга веб
	ресурсов, ограничивая количество обращений к указанным в его
	конфигурации ресурсам сайта. Ограничение ставится на количество
	запросов даннного типа за указанный временной интервал с одного и
	того же IP-адреса.  FloodGuard может применятся как к отдельным
	компонентам сайта так и ко всему сайту в целом.

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

	Остальные пакеты пока в работе.

 3. Zope нужно обслуживать: запускать, останавливать, паковать, бакапить, и
 т.п.: мы полностью переписали все скрипты окружения, типа
 /etc/rc.d/init.d/zope, и добавили штук пять своих: неплохие наработки у нас
 были, хотя их и пришлось обобщить. Теперь это удобно.

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

 =========
 Apache
 =========

 Я уже говорил что в апаче бага? В модуле mod_proxy. Честно говоря, у меня
 так и не дошли руки поднять стенд и воссоздать тестовую ситуацию на вашем
 русском апаче, но где-то дня через три его работы я увидел до боли знакомые
 симптомы и Павел пересобрал апач с моим патчем, симптомы после этого прошли,
 а к этому письму я прилагаю патч, описание баги, обоснование патча и
 тестовый скрипт. Теперь к апачу претензий, вроде, нет. Хотя баги в этом
 модуле, безусловно, еще есть - я не шучу, я вижу их проявления, просто это
 не критично.

 Далее следуют подробности баги, взятые из нашей переписки с заказчиками,
 если нужны дополнительные подробности, мы готовы их предоставить, также можем
 предосавить ваш SRPMS вашего апача, в который патч уже добавлен :

 == cut : описание баги ==
Проведенные работы позволили выявить две ошибки в используемых
программных средствах: apache 1.3.20 & MSIE 5.00.2920.0000.

1. Ошибка в mod_proxy apache 1.3.20

Условия проявления:
	
	- Наличие в кеше mod_proxy ресурса с истекшим временем кеширования,
	определенным эвристически (т.е. без использования заголовка Expire).

	- Обращение со стороны клиента к прокси.

Причина ошибки:

	- Прокси выполняет ревалидирование кешированного ресурса с сервером
	посредством запроса с условием If-Modified-Since <Last-Modified>.

	- При получении со стороны сервера ответа со статусом "Not Modified"
	из-за ошибки в модуле mod_proxy, прокси возвращает кешированный
	ресурс с заголовками, полученными от сервера в процессе валидации
	ресурса и не возвращает заголовки, кешированные при более раннем
	обращении (что нарушает требования RFC2068 & RFC1945).

	- Среди этих заголовков появляется заголовок Content-Length со
	значением "0". В соответствии с требованиями RFC2068, UA (MSIE)
	прекращает загрузку тела содержимого по достижении указанной длины,
	но не сообщает об этом пользователю, чем в свою очередь также
	нарушает требования RFC2068. UA HTTP/1.0 (Netscape) докачивает тело
	содержимого и, как правило корректно, отображает его (за
	исключением случаев когда опознание типа содержимого сбивается из-за
	отсутствия заголовка Content-type).

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

Проявление ошибки:

	Недокаченные или наполовину докаченные картинки в MSIE,
	загружающиеся корректно при немедленном повторном обращении к
	ресурсу.

Методы противодействия:

	- (Рекомендуемый и проверенный) Применить прилагаемый патч к
	mod_proxy (apache v.1.3.20)

	ЗАМЕЧАНИЕ: Предлагемый патч может нарушить нормальную работу
	mod_proxy с HTTP/0.9 серверами (я не то что бы знаю, я просто не
	проверял).

К письму также прилагается патч для mod_proxy (proxy_patch.diff) и тестовая
тулза на питоне (proxy_test.py). Рекомендации по использованию тестовой
тулзы предоставляются отдельно по запросу: IMHO, исходного кода более чем
достаточно, но вот испольованная нами командная строка теста:

proxy_test.py -vvv -s 600  fnf.bpn.iig a.lst

Где a.lst (список ZImage-морфных ресурсов сервера) - может быть получен
посредством manage_findForm.  При корректном завершении теста результаты
должны быть такими:

Тестирование окончено 
---------------------- 
Ошибок HTTP при инициализации кеша 4 
Ошибок при первой загрузке (тело,заголовки) (0,0) 
Ошибок при второй загрузке (тело,заголовки) (0,0) 
Немодифицированных ресурсов при первой загрузке 0 
Немодифицированных ресурсов при второй загрузке 0 
Ошибок HTTP при валидировании кеша 0
----------------------

При некорректном (при обнаружении ошибки) результаты
могут быть, например, такими:
Тестирование окончено
---------------------- 
Ошибок HTTP при инициализации кеша 4 
Ошибок при первой загрузке (тело,заголовки) (0,15) 
Ошибок при второй загрузке (тело,заголовки) (0,14) 
Немодифицированных ресурсов при первой загрузке 0
Немодифицированных ресурсов при второй загрузке 0 
Ошибок HTTP при валидировании кеша 0
----------------------

ЗАМЕЧАНИЕ: 15 & 14 ошибок - это неверно отданные заголовки.

Настройки апача 1.3.20:

На тестовом сервере использовалась модульная версия (т.е. mod_proxy &
mod_rewrite были собраны как модули) со следующими параметрами кеширования:

ProxyRequests On
CacheRoot "/hosting/pokolenie_ok/cache"
CacheSize 1048576
CacheGcInterval 1
CacheMaxExpire 0.1
CacheDefaultExpire 0.05

Сразу замечу, что такие параметры являются суб-оптимальными и не должны
использоваться на реальном сервере.
 == cut ==
 == cut : patch ==
see attach
 == cut ==
 == cut : скрипт тестирующий наличие баги ==
see attach
 == cut ==

 =========
 Perl
 =========
 Perl, тоже падал.
 
 Мы используем объектные возможности Perl в конструкторе объекта открываем
 DBM (dbmopen) и сохраняем ссылку на хеш в атрибуте объекта. В деструкторе
 мы честно закрываем базу (dbmclose), в этот момент Perl падает.  Если базу
 явно не закрывать, возникает вопрос о том, закроет ли Perl ее коректно, что
 очень важно для CGI скриптов.
 
 Пример скрипта:

== cut ==
#!/usr/bin/perl
package Authen;  

sub new {
        my $proto = shift;
        my $class = ref($proto) || $proto;
        my $self  = {}; 
        bless($self,$class);
	my %LT;
	dbmopen(%LT, "test_dbmopen", 0666) || die "Can't open test_dbm.db because of 
$!\n";
	$self->{'LT'} = \%LT;
        return $self;
}

sub DESTROY {
        my $self = shift;
	dbmclose(%{$self->{'LT'}});
	return 1;
}

package main;

$test = Authen->new();
== cut ==

Мы пересобирали Perl с поддержкой разных DB (DB3, DB2, GDB), ошибка
проявлялась везде..


 =========
 Sendmail
 =========

 Здесь тоже были свои проблемы. Скорее настройки, чем баги, но на самом деле
 хотелось бы узнать: кто-то его поддерживает? Нет-нет, мы не пытаемся
 предложить нашу кандидатуру, но хотелось бы посоветоваться. С настройкой
 авторизации у меня были серьезные проблемы, хотя, кажется, я их
 благополучно решил, а вот starttls в конце-концов пришлось отложить до
 появления большего количества свободного времени. Опять-таки, ваши сэмплы в
 этом отношении не были работоспособны, в основном я пользоавался методичкой
 с sendmail.org.

 =========
 Остальное
 =========

 Остальное - это уже скорее настройки под конкретное применение, и
 представляют интерес скорее полемический, чем практический, а потому и
 высказываются только в плане общей полемики:
 
 1. Представляется разумным, имея на борту дистрибутива две базы данных,
 собирать все пакеты с их поддержкой, если таковая есть. Как пример приведем
 ProFTPD... Зависимость в этом случае, видимо, лучше попробовать подавить.

 2. Представляется разумным, поставлять апач уже настроенный под виртуальный
 хостинг и с несколько облагороженными ErrorMessage. Есть несколько
 полуразумных вариантов такой настройки, есть и специальный модуль, и
 настроить апач самим, конечно, не трудно, но зачем всем каждый раз
 изобретать велосипед?  Не самый лучший вариант есть у нас, но, я думаю,
 самостоятельной ценности он не представляет, а если такая работа будет
 проводится - мы бы приняли участие, по крайней мере, в обсуждении.

 3. Когда-то давным давно, лет, может быть, даже и 6ть назад, достаный
 большим количеством файлов ~/.* , я попросил администратора того дуникса
 дописать в /etc/passwd каталог .home после домашнего, а в .bashrc добавил
 строчку

	function cd () { if [ "$1" ]; then command cd "$1"; else command cd ~/..; fi 
}

 и перестал все время видеть ~/.*.

 С тех пор это вошло в привычку. Позже, ситуацию сильно усугубило ~/.kde,
 ~/public_html, gnome и ряд других аналогичных иерархий: похоже, мы
 благополучно движемся к тому, что бы понятие "домашнего каталога"
 разделить на два: каталог с профайлами и рабочий каталог по умолчанию. Свой
 шаг в этом направлении я уже рассказал: он очень короткий, хотя многие
 находят его удобным, а не известно ли вам каких-то более серъезных шагов в
 этом направлении?  Правда, hier благополучно заминает вопрос планировки
 домашних каталогов....
 
 4. Язык Ruby. Мы обратили внимание на этот пакет в дистрибъюшене, хотелось
 бы узнать, кем и как он поддерживается. Мы им не пользуемся, но много
 читали в прессе о проектах на его основе, часть из них представляет для нас
 интерес, отсюда и вопрос.
-----------------------------------------------------------------------




-- 
Андрей Орлов
ведущий инженер IIG
101028, Москва, Хохловский пер.,
10, стр. 6
тел.: +7 (095) 9174920
тел/факс: +7 (095) 2582524
www.iig.ru, aorlov@iig.ru



[-- Attachment #2.1.2: Патч для модпрокси --]
[-- Type: text/x-c, Size: 354 bytes --]

 diff -urN proxy/proxy_http.c proxy.new/proxy_http.c
--- proxy/proxy_http.c	Fri Feb  9 15:40:27 2001
+++ proxy.new/proxy_http.c	Mon Jun 18 17:58:44 2001
@@ -449,9 +449,10 @@
 
 /* no headers */
 	resp_hdrs = ap_make_table(p, 20);
+/* Исправлено, Андрей Орлов */
+        c->hdrs = resp_hdrs;
     }
 
-    c->hdrs = resp_hdrs;
 
     ap_kill_timeout(r);

[-- Attachment #2.1.3: Тест для модпрокси --]
[-- Type: application/x-python, Size: 6781 bytes --]

#! /usr/bin/python
"""
%s [<Опции>] <хост> <файл со списком ресурсов> 

Опции:
	-h	Этот текст
	-v	Сообщения
	-i	Тестирование на неполных запросах
	-m	Тестирование с повторным условным запросом
	-u	Использовать HTTP/1.1
	-s	Время ожидания между первой и второй стадией теста
	--ign	Игнорировать заголовок
	--all	Все заголвки
"""

import socket
import posix
import re
import string
import rand
import sys
import getopt
import md5
import time

verbose_level		= 0
is_incomplete		= 0
sleep			= 60
ignored			= ['Date']
http_version		= 'HTTP/1.0'
(err_body1,err_hdr1)	= (0,0)
(err_body2,err_hdr2)	= (0,0)
http_error1		= 0
http_error2		= 0
notmodify1		= 0
notmodify2		= 0
is_cond			= 0
HttpError		= 'Ошибка HTTP-протокола'
NotModified		= 'Ресурс не был модифицирован с момента предыдущей загрузки'

def verbose(msg,level=1) :
	""" Вывод трассировочного сообщения """
	if level <= verbose_level :
		sys.stdout.write(msg + "\n")
		sys.stdout.flush()	

def error(msg,err=0) :
	""" Вывод сообщения об ошибке и выход """
	if err :
		sys.stdout.write("Ошибка: %s\n" % msg)
	else :
		sys.stdout.write("%s\n** Операция завершена **\n" % msg)

	sys.stdout.flush()
	sys.exit(err)

hdrs_reg = re.compile('^([^:]*):')
def http_load(item,last_modified=None) :
	item = string.strip(item)
	verbose('\nТянем %s' % item, 2)
	hdrs = {}
	sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
	sock.connect('okf.bpn.iig',80)
	f = sock.makefile('r+',1)
	f.write('GET http://%s/%s %s\n' % (args[0],string.strip(item),http_version))
#	print 'GET http://%s/%s %s\n' % (args[0],string.strip(item),http_version)
	if last_modified :
		f.write('If-Modified-Since: %s\n' % last_modified)
#		print 'If-Modified-Since: %s\n' % last_modified
	f.write('\n')
	
	size = None
	s=f.readline()
#	print s
	try :
		http_res = int(string.split(s)[1])
	except :
		raise HttpError

	if http_res != 200 :
		if http_res == 304 :
			verbose('Ответ: %s NotModified' % item,1)
			raise	NotModified
		else :
			verbose('Ошибка %s %u' % (item,http_res),1)
			raise	HttpError
		
	while len(s) : # Катя, отвали
		if s == '\r\n' :
			if size :
				verbose('Начинаем загрузку URL длиной %u' % size,4)
				if is_incomplete :
					size_load = int(size * float(rand.rand())/(2**15-1))
				else :
					size_load = size

				body = f.read(size_load)
				verbose('Загрузили %u из %u (%u)' % (size_load,size,len(body)),4)
				break
			else :
				verbose('Длина не указана, качаем все что есть',4)
				body = ""
				while 1 :
					s = f.read(512)
					if not s :
						break
					body = body + s
				break
					
		else :
			m = hdrs_reg.match(s)
			if m :
				(b,e) = m.regs[1]
				h = s[b:e]
				s = string.strip(s)
				hdrs[h] = s
				if h == 'Content-Length' :
					size = int(string.split(s)[1])
				verbose('Найден заголовок %s (%s)' % (h,s),5)
		s=f.readline()

	sock.close()
	return (string.join(map(lambda x : hex(ord(x))[2:4],md5.md5(body).digest()),''),hdrs)

def header_cmp(h_old,h_new) :
	res = 0
	for item in h_old.keys() :
		if item not in ignored :
			try :
				if h_old[item] != h_new[item] :
					res = res + 1
					verbose('Не совпали заголовки %s\n -- %s\n -- %s' % (item,h_old[item],h_new[item]),3)
			except KeyError :
				res = res + 1
				verbose('Во вновь отданных данных нет заголовка %s' % h_old[item],3)

	for item in h_new.keys() :
		if item not in ignored :
			if not h_old.has_key(item) :
				res = res + 1
				verbose('Во вновь отданных данных есть лишний заголовок %s' % h_new[item],3)
			
	return res

opts,args = getopt.getopt(sys.argv[1:],"huvims:",['ign=','all'])
for opt,val in opts :
	if opt == '-h' :
		print __doc__ % sys.argv[0]
		error('При выводе помощи никакие операции не выполняются')
	elif opt == '-v' :
		verbose_level = verbose_level + 1
	elif opt == '-i' :
		verbose('Выполняем тестирование на неполных запросах',1)
		is_incomplete = 1
	elif opt == '-m' :
		verbose('Выполняем тестирование на условных запросах',1)
		is_cond	= 1
	elif opt == '-u' :
		verbose('Будем использовать HTTP/1.1',1)
		http_version = 'HTTP/1.1'
	elif opt == '-s' :
		sleep = string.atoi(val)
		verbose('Пауза %u секунд' % sleep,1)
	elif opt == '--all' :
		ignored = []
		verbose('Проверяем все заголовки',1)
	elif opt == '--ign' :
		ignored.append(val)
		verbose('Игнорируем заголовок %s' % val,1)


if len(args) != 2 :	error('Неверная командная строка')

verbose('Начали',0)
verbose('Набиваем кеширующий прокси кешированными ресурсами',1)
urlmd5 = {}

for item in open(args[1]).readlines() :
	try :
		(body,hdrs) = http_load(item)
		if is_cond :
			try :
				urlmd5[item] = (body,hdrs,string.strip(hdrs['Last-Modified'][len('Last-Modified:'):]))
			except KeyError :
				verbose('Нет заголовка Last-Modified - тестирование не будет полным',2)
				urlmd5[item] = (body,hdrs)
		else :
			urlmd5[item] = (body,hdrs)
	except (HttpError,NotModified) :
		verbose('Ошибка при обращении к %s' % item,1)
		http_error1 = http_error1 + 1


verbose('Пауза %u секунд' % sleep,1)
time.sleep(sleep)
verbose('Делаем повторный запрос из прокси',1)
for item in urlmd5.keys() :
#	try :
		if is_cond and len(urlmd5[item]) == 3 :
			last_modify = urlmd5[item][2]
		else :
			last_modify = None

		try :
			(body,hdrs) = http_load(item,last_modify)
			if body != urlmd5[item][0] :
				err_body1 = err_body1 + 1
				verbose('Ответ на запрос не совпал при первом обращении к прокси %s' % item,2)

			if header_cmp(urlmd5[item][1],hdrs) :
				err_hdr1 = err_hdr1 + 1
				verbose('Заголовки ответа на запрос не совпали при первом обращении к прокси %s' % item,2)

			urlmd5[item] = (body,hdrs)

		except NotModified :
			notmodify1 = notmodify1 + 1
			verbose('Ресурс %s не был модифицирован' % item, 2)


		try :
			(body,hdrs) = http_load(item,last_modify)
			if body != urlmd5[item][0] :
				err_body2 = err_body2 + 1
				verbose('Ответ на запрос не совпал при втором обращении к прокси %s' % item,2)

			if header_cmp(urlmd5[item][1],hdrs) :
				err_hdr2 = err_hdr2 + 1
				verbose('Заголовки ответа на запрос не совпали при втором обращении к прокси %s' % item,2)

		except NotModified :
			notmodify2 = notmodify2 + 1
			verbose('Ресурс %s не был модифицирован' % item, 2)

#	except HttpError :
#		verbose('Ошибка при обращении к %s' % item,1)
#		http_error2 = http_error2 + 1

verbose('Тестирование окончено',0)
verbose('----------------------',0)
verbose('Ошибок HTTP при инициализации кеша %u' % http_error1)
verbose('Ошибок при первой загрузке (тело,заголовки) (%u,%u)' % (err_body1,err_hdr1),0)
verbose('Ошибок при второй загрузке (тело,заголовки) (%u,%u)' % (err_body2,err_hdr2),0)
verbose('Немодифицированных ресурсов при первой загрузке %u' % notmodify1, 0)
verbose('Немодифицированных ресурсов при второй загрузке %u' % notmodify2, 0)
verbose('Ошибок HTTP при валидировании кеша %u' % http_error2)
verbose('----------------------',0)

             reply	other threads:[~2002-01-04 19:57 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-01-04 19:57 Aleksey Novodvorsky [this message]
2002-01-04 20:20 ` Alexander Bokovoy
2002-01-05 11:05   ` [devel] bash-completion Michael Shigorin
2002-01-05 13:06     ` Alexander Bokovoy
2002-01-05 15:06       ` Michael Shigorin
2002-01-05 15:40         ` Alexander Bokovoy
2002-01-04 22:55 ` [devel] Re: [Fwd: Рассказ об установке ALTLinux] Mikhail Zabaluev

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3C360933.3DEA49A@altlinux.ru \
    --to=aen@altlinux.ru \
    --cc=devel@altlinux.ru \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

ALT Linux Team development discussions

This inbox may be cloned and mirrored by anyone:

	git clone --mirror http://lore.altlinux.org/devel/0 devel/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 devel devel/ http://lore.altlinux.org/devel \
		devel@altlinux.org devel@altlinux.ru devel@lists.altlinux.org devel@lists.altlinux.ru devel@linux.iplabs.ru mandrake-russian@linuxteam.iplabs.ru sisyphus@linuxteam.iplabs.ru
	public-inbox-index devel

Example config snippet for mirrors.
Newsgroup available over NNTP:
	nntp://lore.altlinux.org/org.altlinux.lists.devel


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git