Newsgroup: it.comp.lang.perl
Titolo: session

Buongiorno a tutti,
sto cercando di fare una applicazioncina con tre script cgi.
Dovrei fare il login nel primo e successivamente l'utente può andare
ad utilizzare uno degli altri due tenendo conto dell'utente con il
quale si è autenticato.
Per fare ciò ho pensato di utilizzare le sessioni (ma se avete idee
migliori ditemelo pure).
Il problema è che nel browser, dopo il login mi appare:
"L'applicazione CGI specificata non ha restituito un insieme completo
di intestazioni HTTP."
Ovviamente, se non utilizzo la funzione "sessionadd" descritta di
seguito, il problema non si pone ma non riesco a tenere traccia, da uno
script all'altro, dell'utente con il quale si ci è autenticati...
Avete qualche ideuzza del motivo?
Sapete come risolvere il problema?
PS: Ovviamente il modulo CGI::Session è installato :-)
Ecco il codice:
PROG PRINCIPALE:
-----------------
use HTML::Template;
use Mio::Modulo;
...
...
my $prog = new Mio::Modulo;
my $template = HTML::Template->new(filename =>
$prog->{'conf'}{'template'});
...
...
else{
		$template->param(AUTH=>"Ciao $utente->{'utente'} SEI AUTENTICATO come
utente $utente->{'tipo'}. Adesso puoi cliccare su una della
applicazioni<br>Per effettuare il login con una altra utenza premi
Index!");
		$template->param(LINKS => $prog->{'conf'}{'linkscripts'});
		$template->param(AUTENTICAZIONE => 1);
		my %tmp;
		$tmp{'UT'}=$utente->{'utente'};
		$tmp{'TIPOUT'}=$utente->{'tipo'};
		$tmp{'FILIALEUT'}=$utente->{'filiale'};
		$prog->sessionadd(%tmp);
	}
...
...
-----------------
MIO MODULO
------------------
sub sessionadd{
	my ($self,%par)=@_;
	my $session = new CGI::Session();
        # send proper HTTP header with cookies:
    print $session->header();
    $session->param(-name=>'pippo', -value=>'pluto');
 
}

 Sapete come risolvere il problema?
Boh, non vedo errori nel codice che hai postato.
L'unica cosa che mi viene in mente è che, in qualche altra parte del
codice, o stampi qualcosa prima di $session->header() oppure stampi di
nuovo gli header dopo $session->header().
print $session->header() stampa correttamente tutti i tuoi header
(Set-Cookie e Content-type, quest'ultimo con valore 'text/html'), quindi 
gli header non vanno ristampati né va inviato niente prima al browser.
Se invece non vuoi delegare l'invio degli header a CGI::Session, 
dovresti generare tu esplicitamente gli header come mostrato nella 
documentazione di CGI:.Session.
Controlla pure di avere le ultime versioni sia di CGI::Session (4.03)
che di CGI (3.11), che è usato nascostamente da CGI::Session, quando
invochi $session->header senza parametri.
Ti posso dare un consiglio?
Usa CGI::Application. Non ci vuole molto per impararlo e ti ripaga
abbondantemente in termini di gestibilità del codice. E faciliterebbe
anche le revisioni del codice da parte degli altri ;-)
Peraltro si integra molto facilmente con HTML::Template (anche se io
personalmente preferisco Template-Toolkit, anch'esso utilizzabile 
facilmente, mediante CGI::Application::Plugin::TT).
Se poi ti servisse, potrei postare il codice per inserire la gestione 
delle sessioni in CGI::Application (CGI::Application::Plugin::Session 
non va usato perché ha un (subdolo) memory leak, che segnalerò 
all'autore non appena avrò il tempo per scrivere un bug report decente o 
una patch).
Ciao,
Emanuele.

Ciao Emanuele.
Se postassi il codice per inserire la gestione delle sessoni in
CGI::Application mi faresti un enorme piacere.
Per quanto riguarda CGI::Application l'ho visto due giorni fa per caso
e mi son fatto l'idea anche io che sia parecchio completo: volevo
dargli un'occhiata fin dalla prossima settimana ma il fatto che tu me
lo consigli mi ha fatto aumentare le aspettative :-)
Per quanto riguarda Template-Toolkit mi potresti spiegare un pochino
meglio cosa sia?
Una sorta di sistema di template per HTML, txt e altro?
Grazie per la risposta e aspetto l'implementazione per le session :-)
Ciao,
       Vittorio

 Grazie per la risposta e aspetto l'implementazione per le session :-)
Di nulla!
=cut
# Schema per l'integrazione di CGI::Session in CGI::Application,
# con l'id di sessione scambiato attraverso un cookie.
# Si assumono le ultime versioni di CGI::Application, CGI::Session e CGI
# ad oggi disponibili su CPAN.
# La tua applicazione, contenuta nel modulo
# MyWebApplication.pm (ad esempio).
package MyWebApplication;
use base 'CGI::Application';
use strict;
use CGI::Session;
# ...
# Il tuo metodo cgiapp_init, che dovrà contenere il blocco
# specificato nel seguito, per la creazione del session object.
sub cgiapp_init {
	my $self = shift;
	# ...
	# Opzionale, se vuoi specificare per il cookie sul client
	# un nome diverso da CGISESSID.
	CGI::Session->name('nome_tuo_cookie');
	# Creazione del session object, con una combinazione di
	# parametri puramente esemplificativa.
	my $session = CGI::Session->new(
		"driver:file;serializer:default",
		$self->query,
		{ Directory => 'path_file_dati_di_sessione_sul_server' }
	);
	$self->param('session', $session);
	# ...
}
# Il tuo metodo cgiapp_postrun, che dovrà contenere il blocco
# specificato nel seguito, necessario per l'invio del cookie.
sub cgiapp_postrun {
	my $self = shift;
	# ...
	my $session = $self->param('session');
	my $cookie = $self->query->cookie(
		-name    => $session->name,
		-value   => $session->id,
		# Settare la durata del cookie come necessario.
		-expires => '+1M'
	);
	$self->header_add(-cookie => $cookie);
	# ...
}
# A questo punto in ogni tuo runmode (grossomodo ne avrai
# uno per ogni pagina generata dalla tua applicazione),
# potrai accedere al session object. Ad esempio in un certo
# runmode puoi valorizzare un certo parametro di sessione...
sub un_certo_runmode {
	my $self = shift;
	# ...
	my $session = $self->param('session');
	$session->param('user_background_color', 'Black');
	# ...
}
# ... E in una successiva invocazione della tua applicazione puoi
# recuperarne il valore, anche in un altro runmode, anche a un mese
# di distanza.
sub un_altro_runmode {
	my $self = shift;
	# ...
	my $session = $self->param('session');
	my $color = $session->param('user_background_color');
	# Qui ad esempio puoi usare $color per generare la
	# pagina con il background personalizzato dall'utente ...
}
# ...
1;
__END__
Per qualsiasi chiarimento o approfondimento fammi sapere.
Ciao,
Emanuele.