Почему CGI :: Session новый и загрузка не удалась (не удалось оттаять ())? - PullRequest
3 голосов
/ 19 сентября 2011

Я попытался использовать библиотеку CGI :: Session, но по какой-то причине мой код не поддерживает постоянную сессию ... это использует Perl Moose для ООП и использует Moose Builders для создания экземпляров _cgi и _sss (сессия) параметры объекта My :: Session ...

ОБНОВЛЕННЫЙ КОД

My :: Роль :: PersistantData

package My::Role::PersistsData;

use Moose::Role;
use namespace::autoclean;
  has '_cgi' => (
           is        => 'rw', 
           isa       => 'Maybe[CGI]', 
           builder   => '_build_cgi'
  );

  has '_sss' => (
           is        => 'rw', 
           isa       => 'Maybe[CGI::Session]',
           builder   => '_build_sss'
  );

My :: Session

    package My::Session;

    use Moose;
    use namespace::autoclean;
    with 'My::Role::PersistsData';  

    use CGI;
    use CGI::Session ('-ip_match');
    use CGI::Carp qw/fatalsToBrowser warningsToBrowser/;

    sub start{
      my($self) = @_;
      my $cgi = $self->cgi();
      $self->log("Session Started!");        
    }


    sub cgi{
      my($self) = @_;
      $self->_cgi = $self->_build_cgi() unless $self->_cgi;
      return ($self->_cgi); 
    }


    sub _build_cgi{
      my($self) = @_; 
      my $cgi = CGI->new();

      if(!$cgi){
        #print "mising cgi";          
      }

      return ( $cgi );
    }


    sub _build_sss{
          my($self) = @_;
          my $cgi = $self->cgi(); 

          my $sid = $cgi->cookie("CGISESSID") || $cgi->param('CGISESSID') || undef;

          $self->log("Session ID Initial is: ".($sid?$sid:"undef"));

          my $sss =  CGI::Session->new(undef, $cgi, {Directory=>'tmp'})  or die CGI::Session->errstr;



          my $cookie = $cgi->cookie(CGISESSID => $sss->id() );


          $self->log("Resulting Session ID is: ".$sid." cookie is: ".$cookie);    

          print $cgi->header( -cookie=>$cookie );

          return ( $sss );
    }

main.pl

use Data::Dumper; 
$Data::Dumper::Sortkeys = 1;

use CGI;
use CGI::Carp qw(fatalsToBrowser);
use My::Session;

$| = 1;
$, = " ";
$\ = "\n <br />";

  my $sss = My::Session->new();      
  $sss->start();
  print Dumper($sss);

Это довольно странно, потому что при первом запуске я получаю фактический идентификатор CGISESSION и могу перенести его при обновлении страницы ...

однако, если я загружаю страницу снова, внезапно $ sss (сессия) возвращается как неопределенное, когда он должен вернуть новый объект Session:

 $sss = new CGI::Session("driver:File", $sid, {Directory=>'/tmp'})

по какой-то причине $ sss возвращается как неопределенное, что означает, что он не инициировал новый сеанс. Несколько настроек моего кода выявили эту ошибку:

new(): failed: load(): couldn't thaw() data using CGI::Session::Serialize::default:thaw(): couldn't thaw. syntax error at (eval 253) line 2, near &quot;/&gt;&quot; 

Я также рылся в CGI :: Session.pm и обнаружил, где выдается эта ошибка. Я думаю, он не может анализировать _DATA или даже читать его ... из-за каких-то странных символов ... "/> "

CGI :: Session.pm

....
    $self->{_DATA} = $self->{_OBJECTS}->{serializer}->thaw($raw_data);
    unless ( defined $self->{_DATA} ) {
        #die $raw_data . "\n";
        return $self->set_error( "load(): couldn't thaw() data using $self->{_OBJECTS}->{serializer} :" .
                                $self->{_OBJECTS}->{serializer}->errstr );
    }

Есть идеи, почему это не работает?

Ответы [ 3 ]

1 голос
/ 20 сентября 2011

Возможно, вы могли бы попробовать (или, по крайней мере, взглянуть на код, чтобы увидеть, как он работает) для некоторого модуля webapp с состоянием. Я использовал Непрерывность , очень крутые вещи.

1 голос
/ 20 сентября 2011

Почему-то вы не можете использовать Data::Dumper или другие теги HTML с CGI::Session

Ответ найден здесь и здесь

Удаление Dumper и вывода HTML решило эту проблему - вроде -

обновлено

Видимо, вы должны используйте escape-коды

 $cgi->escapeHTML ( Dumper($session) );

, и это, наконец, решает эту проблему.

Perl - это боль!

1 голос
/ 19 сентября 2011

Скорее всего, это связано с отправкой другого файла cookie сеанса (был там, ударил по этой стене головой. HARD).

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

Если они действительно различаются, у вас есть 2 варианта:

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

    Мне так и не удалось найти убедительный ответ, но мое приложение состояло из фрейма с внутренним <iframe>, поэтому я подозреваю, что это из-за этого.

  • Если нравлюсь мневы не можете найти основную причину, вы также можете обойти это.

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

    Затем повторно инициализируйте объект сеанса с правильным значением cookie, прежде чем ваш код на стороне сервера запросит данные сеанса.

    Не очень безопасно, раздражает, трудно понять правильно.Но работает.Я бы не рекомендовал это, кроме как в качестве "хакера в крайнем случае"

...