На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Внимательно изучите правила раздела перед созданием темы
0. ПРИЛАГАЙТЕ СВОИ СКРИПТЫ.
1. Прежде чем создать топик, используйте поиск. Возможно это уже обсуждалось.
2. В топике указывайте ОС, режим работы скрипта (CLI|CGI). Очень желателен вывод лог-файлов и того места, куда у вас назначен вывод данных (STDOUT|STDERR)
3. Помните: вы знаете что вы хотите, а форумчане - нет. Поэтому следуйте простому правилу: грамотный развернутый вопрос - грамотный развернутый ответ.
Модераторы: ANDLL
  
    > Слетает скрипт , Timeout waiting for output from CGI script
      Всем привет.

      FreeBSD (Apache+Perl)
      Есть скрипт, работающий бесконечно в качестве веб-сервера (использую use HTTP::Daemon;)

      запускаю его. минут через 5 слетает.
      в логах:
      [Fri Mar 12 13:50:18 2010] [warn] [client х.х.х.х] Timeout waiting for output from CGI script /usr/home/lexa/cgi-bin/proba.pl

      подскажите пожалуйста что это? и как исправить?
        А до того, в течение 5 минут, всё работает?

        Добавлено
        А вообще телепатия говорит о том, что cgi -- это не реверс-прокси, нужное для http-демона.
          Цитата
          А до того, в течение 5 минут, всё работает?

          да. Обрабатывает он в данный момент клиентов или нет - все равно слетает.


          Цитата
          А вообще телепатия говорит о том, что cgi -- это не реверс-прокси, нужное для http-демона.
          да. не правильно изложил мысль.
          Вобщем у меня обычный прокси-сервер написанный на Perl

          Жду помощи :oops:
          Сообщение отредактировано: Lexa F. -
            Можно как-то конкретней?
            Одна строчка лога - это красиво и кратко.
            Но хотелось бы увидеть и сам скрипт.
              пробую этот скрипт:
              ExpandedWrap disabled
                #!/usr/bin/perl
                 
                use HTTP::Daemon;
                use LWP::UserAgent;
                use CGI::Carp qw(fatalsToBrowser);
                use Net::hostent;
                 
                my $port = 4323;
                 
                $SIG{PIPE} = 'IGNORE';
                 
                my $server = HTTP::Daemon->new( LocalPort => $port ) or
                die "Can't start server ($@)" unless defined $server;
                 
                my $ua = LWP::UserAgent->new;
                while (my $connection = $server->accept) {
                #... тут ничего нет. Это для теста.
                }
              висит мин 5 и слетает
              лог:
              ExpandedWrap disabled
                [Mon Mar 15 05:34:07 2010] [warn] [client х.х.х.х] Timeout waiting for output from CGI script /usr/home/lexa/cgi-bin/proba.pl
                [Mon Mar 15 05:34:07 2010] [error] [client х.х.х.х] Premature end of script headers: proba.pl
              Сообщение отредактировано: Lexa F. -
                Далеко не гуру, но...
                Это топорный код, имхо.

                Я, может быть и не прав, но взгляните на этот код:
                ExpandedWrap disabled
                  #!/home/merlyn/bin/perl -Tw
                  use strict;
                  $ENV{PATH} = join ":", qw(/usr/ucb /bin /usr/bin);
                  $|++;
                   
                  ## Copyright (c) 1996 by Randal L. Schwartz
                  ## This program is free software; you can redistribute it
                  ## and/or modify it under the same terms as Perl itself.
                   
                  ## Anonymous HTTP proxy (handles http:, gopher:, ftp:)
                  ## requires LWP 5.04 or later
                   
                  my $HOST = "localhost";
                  my $PORT = "8008";
                   
                  sub prefix {
                    my $now = localtime;
                   
                    join "", map { "[$now] [${$}] $_\n" } split /\n/, join "", @_;
                  }
                   
                  $SIG{__WARN__} = sub { warn prefix @_ };
                  $SIG{__DIE__} = sub { die prefix @_ };
                  $SIG{CLD} = $SIG{CHLD} = sub { wait; };
                   
                  my $AGENT;          # global user agent (for efficiency)
                  BEGIN {
                    use LWP::UserAgent;
                   
                    @MyAgent::ISA = qw(LWP::UserAgent); # set inheritance
                   
                    $AGENT = MyAgent->new;
                    $AGENT->agent("anon/0.07");
                    $AGENT->env_proxy;
                  }
                   
                  sub MyAgent::redirect_ok { 0 } # redirects should pass through
                   
                  {               ### MAIN ###
                    use HTTP::Daemon;
                   
                    my $master = new HTTP::Daemon
                      LocalAddr => $HOST, LocalPort => $PORT;
                    warn "set your proxy to <URL:", $master->url, ">";
                    my $slave;
                    &handle_connection($slave) while $slave = $master->accept;
                    exit 0;
                  }               ### END MAIN ###
                   
                  sub handle_connection {
                    my $connection = shift;   # HTTP::Daemon::ClientConn
                   
                    my $pid = fork;
                    if ($pid) {           # spawn OK, and I'm the parent
                      close $connection;
                      return;
                    }
                    ## spawn failed, or I'm a good child
                    my $request = $connection->get_request;
                    if (defined($request)) {
                      my $response = &fetch_request($request);
                      $connection->send_response($response);
                      close $connection;
                    }
                    exit 0 if defined $pid;   # exit if I'm a good child with a good parent
                  }
                   
                  sub fetch_request {
                    my $request = shift;      # HTTP::Request
                   
                    use HTTP::Response;
                   
                    my $url = $request->url;
                    warn "fetching $url";
                    if ($url->scheme !~ /^(http|gopher|ftp)$/) {
                      my $res = HTTP::Response->new(403, "Forbidden");
                      $res->content("bad scheme: @{[$url->scheme]}\n");
                      $res;
                    } elsif (not $url->rel->netloc) {
                      my $res = HTTP::Response->new(403, "Forbidden");
                      $res->content("relative URL not permitted\n");
                      $res;
                    } else {
                      &fetch_validated_request($request);
                    }
                  }
                   
                  sub fetch_validated_request {
                    my $request = shift;  # HTTP::Request
                   
                    ## uses global $AGENT
                   
                    ## warn "orig request: <<<", $request->headers_as_string, ">>>";
                    $request->remove_header(qw(User-Agent From Referer Cookie));
                    ## warn "anon request: <<<", $request->headers_as_string, ">>>";
                    my $response = $AGENT->request($request);
                    ## warn "orig response: <<<", $response->headers_as_string, ">>>";
                    $response->remove_header(qw(Set-Cookie));
                    ## warn "anon response: <<<", $response->headers_as_string, ">>>";
                    $response;
                  }


                И вот еще пример.
                Просто в вашем коде я не вижу никаких обработок, никаких форков =)
                  Цитата Nadz Goldman @
                  Просто в вашем коде я не вижу никаких обработок, никаких форков =)

                  ну да..убрал пока все лишнее..но слетать то он в таком виде не должен! верно?
                  спасибо за примеры, возможно переделаю

                  однако вопрос по моему коду все-равно остается открытым. очень хочется докопаться до истины..может с настройками FreeBSD или Perl проблема?!.
                  Сообщение отредактировано: Lexa F. -
                    Нет. ОС дает вам ресурсы, а вы просто ресурсы неправильно отрабатываете =)

                    Т.е. если это - прокси-сервер, то он работать... кхм... должен, но нииизэээнькооо-нииизэээнькооо =)

                    Завтра/послезавтра обещаю покопаться.
                      Nadz Goldman, ваш скрипт слетает точно так же :(

                      Чтож такое то ?? :wall:
                      Сообщение отредактировано: Lexa F. -
                        Если я правильно понял (это ведь был лог апача?) - то ты всё-таки пытаешься запускать эти скрипты из под апача, как CGI?
                        Это не CGI, а "самостоятельные" скрипты. CGI скрипт должен обработать запрос, вернуть апачу то, что нужно отослать клиенту и умереть, а не висеть в бесконечном цикле. Если он цепляется за жизнь, то апач его прибивает.
                          Цитата Adil @
                          Если я правильно понял (это ведь был лог апача?) - то ты всё-таки пытаешься запускать эти скрипты из под апача, как CGI?
                          Это не CGI, а "самостоятельные" скрипты. CGI скрипт должен обработать запрос, вернуть апачу то, что нужно отослать клиенту и умереть, а не висеть в бесконечном цикле. Если он цепляется за жизнь, то апач его прибивает.

                          а как быть?
                          мне нужно запустить скрипт и чтоб он висел постоянно.
                            Цитата Lexa F. @
                            мне нужно запустить скрипт и чтоб он висел постоянно.
                            Просто его запустить. Из консоли, например :)

                            Добавлено
                            Можно с & в конце команды, чтобы отлучить его от текущей консоли.
                              запускаю putty, захожу в каталог со скриптом, запускаю: ./proba.pl
                              висит 5 мин и слетает :'( .
                              как еще можно попробовать запустить?
                              и можно пример с & ?
                                Может у тебя и ssh (или к кому там поключаешься) отключает за бездействие? Посмотри в его логах. И ты, кстати, так и не ответил, чей это был лог.
                                ExpandedWrap disabled
                                  localhost#./proba.pl&
                                Кстати, если это ssh отключает, то & должно помочь.
                                  Цитата Adil @
                                  И ты, кстати, так и не ответил, чей это был лог.

                                  да. лог был апача

                                  спасибо, сейчас попробую ваш вариант
                                    Adil, спасибо Вам огромное :good:
                                    действительно, запустиль с помощью & и все стало ок.

                                    ...пустяк, а такую проблему мне создал :jokingly:
                                    Сообщение отредактировано: Lexa F. -
                                      Да не за что.
                                      Может на "ты"? На форуме "выкать" как то не привычно.
                                        ок ;)
                                        еще раз тебе спасибо
                                          можно вопросик.
                                          как правильно?
                                          1.
                                          ExpandedWrap disabled
                                            #...
                                            my $server = HTTP::Daemon->new( LocalPort => $port ) or
                                            die "Can't start server ($@)" unless defined $server;
                                             
                                            my $ua = LWP::UserAgent->new; # <<<<<<<<<---
                                            while (my $connection = $server->accept) {
                                              $pid = fork();
                                              if ($pid == 0){
                                              #...
                                              my $resp = $ua->simple_request($request);
                                              #...
                                              }
                                            #..

                                          2.
                                          ExpandedWrap disabled
                                            #...
                                            my $server = HTTP::Daemon->new( LocalPort => $port ) or
                                            die "Can't start server ($@)" unless defined $server;
                                             
                                            while (my $connection = $server->accept) {
                                              $pid = fork();
                                              if ($pid == 0){
                                              my $ua = LWP::UserAgent->new; # <<<<<<<<<---
                                              #...
                                              my $resp = $ua->simple_request($request);
                                              #...
                                              }
                                            #..
                                            Да вообщем-то - без разницы. В первом варианте объект Агент висит в памяти родительского процесса, где, в принципе, не используется, но зато не надо тратить время на его создание в дочернем процессе, как это получается во втором варианте. Т.е. обычная дилемма - размер/быстродействие.
                                              так во 2 варианте при каждом подключении будет создаваться новый Агент.
                                              а если подключений в минуту около 1000
                                              или ничего страшного? и нужно ли его уничтожать потом? как?

                                              мне самое главное - скорость!
                                                Цитата Lexa F. @
                                                и нужно ли его уничтожать потом? как?
                                                Это перл, он сам подчистит, да и сам по себе удалится при завершение процесса. Если нужно быстродействие - то первый вариант предпочтительней, конечно.
                                                  спасибо.
                                                  чтоб добить вопрос: при одновременном использовании Агента в 1000 форках косяков не будет?
                                                    Не знаю, не пробовал. Попробуешь - расскажи тут :)

                                                    Добавлено
                                                    Тут подводный камень - если только Агент уже при создании занимает исходящий порт. Тогда они - в каждом пооцессе свой экземпляр - могут его не поделить. Но это просто проверить на не таком большом числе форков.
                                                    0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                                    0 пользователей:


                                                    Рейтинг@Mail.ru
                                                    [ Script execution time: 0,0573 ]   [ 15 queries used ]   [ Generated: 18.07.25, 04:45 GMT ]