Главная страница


ru.cgi.perl

 
 - RU.CGI.PERL ------------------------------------------------------------------
 From : Andrey Sapozhnikov                   2:5020/400     25 Jun 2004  18:08:06
 To : Alexander V. Gaiduk
 Subject : Re: mod_perl - глюк?
 -------------------------------------------------------------------------------- 
 
 Alexander V. Gaiduk пишет:
 
 > стал ковырять дальше по исходникам Apache::ASP дополз до BinaryRead...
 > там они просто читают из закэшированного буфера: $r->read($data, $length);
 > получаем 7.5 кило !
 > 
 > это же под виндой читает ВСЁ !!!
 > 
 > дальше стал исследовать саму отправку данных методом POST - его отличия
 > линуховой и виндовой реализации mod_perl.
 > 
 > нарисовал простейший скриптик, где читаю:
 >   read(STDIN, $data, $ENV{'CONTENT_LENGTH'});
 > под виндой - все читает, под линухом 7.5 кило!
 > 
 > выяснилось, что если читать в цикле:
 > while (read(STDIN, $buf, $ENV{'CONTENT_LENGTH'})>0) {$data .= $buf;}
 > то и в виндозе и в линухе читается всё !!!
 > 
 > причем при детальном исследовании оказалось, что в виндозе все данные
 > сразу помещаются в буфер чтения STDIN в mod_perl, а в линухе
 > буфер чтения ограничен 8000 байтами, но тем не менее все данные от туда
 > тоже можно вычитать (читать - пока читаются)...
 > 
 > пришлось такой циклик воткнуть в Apache::ASP::Request
 > в функцию BinaryRead - после этого все поехало прально.
 > 
 > Скажите, почему такое разное поведение mod_perl в линухе и в вындосе?
 
 Различное поведение обусловлено совершенно разными системными
 вызовами чтения файла/потока. Дело в том, что многие программисты
 почему-то опускают тот факт, что системный вызов read(2) в unix
 вовсе не обязан считать столько байт, сколько его попросили. Ситуация
 когда считано меньше запрошенного называется "short read" или
 "partial read". Почему-то большинство программистов склонны считать,
 что "partial read" возникает только при неблокирующем чтении (тут все
 логически понятно - прочитали сколько смогли, ждать не велено), при
 достижении конца файла (прочитали сколько осталось, больше читать нечего),
 и при чтении из терминальных устройств (там вообще сложная песня -
 количество считанных байт зависит от целого ряда параметров установленных
 через интерфейс termio или termios). Однако POSIX.1 (ISO/IEC 9945-1:1990:
 section 6.4.1.2, lines 125-128) явно описывает "partial read" который
 возникает при получении сигнала процессом. В этом случае, если не было
 считано ни одного байта read(2) должен вернуть -1, [EINTR], иначе -
 количество считанных байт. Учитывая то, что в программах сложнее hello_world.c
 предсказать моменты прихода сигналов зачастую весьма трудно, никогда
 не следует закладываться на то, что read вернет весь запрошенный объем
 данных. Так что поведение Вашего примера с read(STDIN, $data, ...
 вполне закономерно и допустимо (описание функции read не гарантирует
 полного чтения). Так же закономерно и допустимо поведение функции
 BinaryRead в модуле Apache::ASP::Request, поскольку она, в отличие
 от Вашего примера, использует метод read принадлежащий классу Apache:
 
 perldoc Apache:
 ...
         $r->read($buf, $bytes_to_read, [$offset])
             This method is used to read data from the client, looping until it
             gets all of $bytes_to_read or a timeout happens.
 
             An offset may be specified to place the read data at some other
             place than the beginning of the string.
 
             In addition, this method sets a timeout before reading with
             "$r->soft_timeout".
 ...
 
 Как мы видим, Apache явно обещал читать пока не вычитает все, либо не случится
 таймаут. А теперь глядим в документацию к mod_perl2:
 
 http://perl.apache.org/docs/2.0/api/Apache/RequestIO.html#C_read_ :
 
 Read data from the client.
 
    $read_count = $r->read($buffer, $len, $offset);
 
 META: same as CORE::read, minus the filehandle argument
 
      * obj: $r (Apache::RequestRec)
      * arg1: $buffer (scalar)
      * arg2: $len (scalar)
      * arg3: $offset (number)
      * ret: $read_count (number)
 
        How many characters were actually read
 
 Поведение существенным образом изменилось. Теперь никто уже не
 обещает вычитать все. Обеспечивать совместимость mod_perl2 с
 mod_perl задача модуля Apache2/Apache/compat.pm, однако никто
 не обещал 100% совместимости.
 
 В заключение - 3 основных вопроса русской интеллигенции:
 
 Q. Кто виноват?
 A. с одной стороны никто не виноват. С другой стороны -
 все в равной степени уроды. Авторы некоторых модулей
 apache (не путать с mod_perl и Apache.pm) подменяют
 сокет пайпом (AFAIK mod_gzip так поступал для реализации
 компрессии на лету). Авторы mod_perl2 не обеспечивают 100%
 совместимости. Авторы Apache::ASP либо до сих не портировались
 под mod_perl2... Вероятно и авторы самого apache тоже
 где-то облажались (обоснование опущено).
 
 Q. Что делать?
 А. Логичнее всего поправить либо Apache::compat либо Apache::ASP.
 
 Q. Кто бежит за "Клинским"?
 A. ...
 
 -- 
 Андрей
 
 --- ifmail v.2.15dev5.3
  * Origin: Demos online service (2:5020/400)
 
 

Вернуться к списку тем, сортированных по:

 Тема:    Автор:    Дата:  
 mod_perl - глюк?   Alexander V. Gaiduk   21 Jun 2004 14:25:54 
 Re: mod_perl - глюк?   Artem Chuprina   22 Jun 2004 14:17:40 
 Hа: mod_perl - глюк?   Alexander V. Gaiduk   22 Jun 2004 15:51:33 
 Re: Hа: mod_perl - глюк?   Artem Chuprina   23 Jun 2004 22:37:38 
 Hа: Hа: mod_perl - глюк?   Alexander V. Gaiduk   24 Jun 2004 12:11:43 
 Re: Hа: Hа: mod_perl - глюк?   Artem Chuprina   24 Jun 2004 15:25:38 
 Hа: Hа: Hа: mod_perl - глюк?   Alexander V. Gaiduk   24 Jun 2004 17:14:12 
 Re: Hа: Hа: Hа: mod_perl - глюк?   Artem Chuprina   24 Jun 2004 21:04:23 
 Re: mod_perl - глюк?   Andrey Sapozhnikov   25 Jun 2004 18:08:06 
 Hа: mod_perl - глюк?   Alexander V. Gaiduk   28 Jun 2004 11:30:48 
 Re: Hа: mod_perl - глюк?   Andrey Sapozhnikov   28 Jun 2004 16:01:20 
Архивное /ru.cgi.perl/6577ef49a68a.html, оценка 2 из 5, голосов 10
Яндекс.Метрика
Valid HTML 4.01 Transitional