• Publicidad

Cómo detectar cuándo cierran una ventana desde el cgi

Todo lo relacionado con el desarrollo Web con Perl: desde CGI hasta Mojolicious

Cómo detectar cuándo cierran una ventana desde el cgi

Notapor Voltus87 » 2011-02-02 14:07 @630

Hola a todos.

No me gustan las introducciones así que aquí va mi pregunta:

¿Es posible detectar cuándo se cierra una ventana (popup) lanzada desde un cgi escrito en Perl?
¿Cómo?

Estoy iniciándome en Perl y necesito orientación.

Gracias por adelantado.
Voltus87
Perlero nuevo
Perlero nuevo
 
Mensajes: 2
Registrado: 2011-02-02 13:42 @612

Publicidad

Re: Cómo detectar cuándo cierran una ventana desde el cgi

Notapor explorer » 2011-02-02 14:12 @633

Bienvenido a los foros de Perl en Español, Voltus87.

Sí, sí que se puede. Solo hay que adjuntar un evento al unload() de la marca <body>, que haga una petición al servidor web, por ejemplo, que haga una llamada al mismo CGI (o a otro), con una determinada URL que indique que la ventana se ha cerrado.

Por ejemplo: /programa.cgi?action=ventanacerrada
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Cómo detectar cuándo cierran una ventana desde el cgi

Notapor Voltus87 » 2011-02-02 16:11 @716

Muchas gracias por responder, explorer.

Ahora mismo no entiendo lo que me dices pero al menos tengo por dónde empezar a buscar.

Solo quisiera saber si la solución que me das se aplica al siguiente entorno:

La aplicación es un portal cautivo (Chillispot) que escucha el trafico HTTP de un cliente y ante un intento de acceso desde un navegador te redirige a una página que es precisamente un cgi (hotspotlogin.cgi)
donde te obliga a autenticarte. Si tus credenciales son correctas te levanta un popup (en otra ventanita) donde te muestra tu estado y el tiempo de conexión.

Ese popup es el que quiero que, en caso de que el usuario lo cierre, provoque que se cierre la sesión de dicho usuario.

Ahora lo que me propones ¿tendría que añadirlo en el cuerpo del cgi?

Saludos y más gracias.

PD. Este es el cgi por si lo puedes revisar.

#!/usr/bin/perl

# chilli - ChilliSpot.org. A Wireless LAN Access Point Controller
# Copyright (C) 2003, 2004 Mondru AB.
#
# The contents of this file may be used under the terms of the GNU
# General Public License Version 2, provided that the above copyright
# notice and this permission notice is included in all copies or
# substantial portions of the software.

# Redirects from ChilliSpot daemon:
#
# Redirection when not yet or already authenticated
# notyet: ChilliSpot daemon redirects to login page.
# already: ChilliSpot daemon redirects to success status page.
#
# Response to login:
# already: Attempt to login when already logged in.
# failed: Login failed
# success: Login succeded
#
# logoff: Response to a logout


# Shared secret used to encrypt challenge with. Prevents dictionary attacks.
# You should change this to your own shared secret.
#$uamsecret = "ht2eb8ej6s4et3rg1ulp";

# Uncomment the following line if you want to use ordinary user-password
# for radius authentication. Must be used together with $uamsecret.
#$userpassword=1;

# Our own path
$loginpath = $ENV{'SCRIPT_URL'};

use Digest::MD5 qw(md5 md5_hex md5_base64);

# Make sure that the form parameters are clean
$OK_CHARS='-a-zA-Z0-9_.@&=%!';
$| = 1;
if ($ENV{'CONTENT_LENGTH'}) {
read (STDIN, $_, $ENV{'CONTENT_LENGTH'});
}
s/[^$OK_CHARS]/_/go;
$input = $_;


# Make sure that the get query parameters are clean
$OK_CHARS='-a-zA-Z0-9_.@&=%!';
$_ = $query=$ENV{QUERY_STRING};
s/[^$OK_CHARS]/_/go;
$query = $_;


# If she did not use https tell her that it was wrong.
if (!($ENV{HTTPS} =~ /^on$/)) {
print "Content-type: text/html\n\n
<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">
<html>
<head>
<title>ChilliSpot Login Failed</title>
<meta http-equiv=\"Cache-control\" content=\"no-cache\">
<meta http-equiv=\"Pragma\" content=\"no-cache\">
</head>
<body bgColor = '#c0d8f4'>
<h1 style=\"text-align: center;\">ChilliSpot Login Failed</h1>
<center>
Login must use encrypted connection.
</center>
</body>
<!--
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<WISPAccessGatewayParam
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
xsi:noNamespaceSchemaLocation=\"http://www.acmewisp.com/WISPAccessGatewayParam.xsd\">
<AuthenticationReply>
<MessageType>120</MessageType>
<ResponseCode>102</ResponseCode>
<ReplyMessage>Login must use encrypted connection</ReplyMessage>
</AuthenticationReply>
</WISPAccessGatewayParam>
-->
</html>
";
exit(0);
}


#Read form parameters which we care about
@array = split('&',$input);
foreach $var ( @array )
{
@array2 = split('=',$var);
if ($array2[0] =~ /^UserName$/) { $username = $array2[1]; }
if ($array2[0] =~ /^Password$/) { $password = $array2[1]; }
if ($array2[0] =~ /^challenge$/) { $challenge = $array2[1]; }
if ($array2[0] =~ /^button$/) { $button = $array2[1]; }
if ($array2[0] =~ /^logout$/) { $logout = $array2[1]; }
if ($array2[0] =~ /^prelogin$/) { $prelogin = $array2[1]; }
if ($array2[0] =~ /^res$/) { $res = $array2[1]; }
if ($array2[0] =~ /^uamip$/) { $uamip = $array2[1]; }
if ($array2[0] =~ /^uamport$/) { $uamport = $array2[1]; }
if ($array2[0] =~ /^userurl$/) { $userurl = $array2[1]; }
if ($array2[0] =~ /^timeleft$/) { $timeleft = $array2[1]; }
if ($array2[0] =~ /^redirurl$/) { $redirurl = $array2[1]; }
}

#Read query parameters which we care about
@array = split('&',$query);
foreach $var ( @array )
{
@array2 = split('=',$var);
if ($array2[0] =~ /^res$/) { $res = $array2[1]; }
if ($array2[0] =~ /^challenge$/) { $challenge = $array2[1]; }
if ($array2[0] =~ /^uamip$/) { $uamip = $array2[1]; }
if ($array2[0] =~ /^uamport$/) { $uamport = $array2[1]; }
if ($array2[0] =~ /^reply$/) { $reply = $array2[1]; }
if ($array2[0] =~ /^userurl$/) { $userurl = $array2[1]; }
if ($array2[0] =~ /^timeleft$/) { $timeleft = $array2[1]; }
if ($array2[0] =~ /^redirurl$/) { $redirurl = $array2[1]; }
}


$reply =~ s/\+/ /g;
$reply =~s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/seg;

$userurldecode = $userurl;
$userurldecode =~ s/\+/ /g;
$userurldecode =~s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/seg;

$redirurldecode = $redirurl;
$redirurldecode =~ s/\+/ /g;
$redirurldecode =~s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/seg;

$password =~ s/\+/ /g;
$password =~s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/seg;

# If attempt to login
if ($button =~ /^Login$/) {
$hexchal = pack "H32", $challenge;
if (defined $uamsecret) {
$newchal = md5($hexchal, $uamsecret);
}
else {
$newchal = $hexchal;
}
$response = md5_hex("\0", $password, $newchal);
$pappassword = unpack "H32", ($password ^ $newchal);
#sleep 5;
print "Content-type: text/html\n\n";
print "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">
<html>
<head>
<title>ChilliSpot Login</title>
<meta http-equiv=\"Cache-control\" content=\"no-cache\">
<meta http-equiv=\"Pragma\" content=\"no-cache\">";
if ((defined $uamsecret) && defined($userpassword)) {
print " <meta http-equiv=\"refresh\" content=\"0;url=http://$uamip:$uamport/logon?username=$username&password=$pappassword&userurl=$userurl\">";
} else {
print " <meta http-equiv=\"refresh\" content=\"0;url=http://$uamip:$uamport/logon?username=$username&response=$response&userurl=$userurl\">";
}
print "</head>
<body bgColor = '#c0d8f4'>";
print "<h1 style=\"text-align: center;\">Logging in to ChilliSpot</h1>";
print "
<center>
Please wait......
</center>
</body>
<!--
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<WISPAccessGatewayParam
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
xsi:noNamespaceSchemaLocation=\"http://www.acmewisp.com/WISPAccessGatewayParam.xsd\">
<AuthenticationReply>
<MessageType>120</MessageType>
<ResponseCode>201</ResponseCode>
";
if ((defined $uamsecret) && defined($userpassword)) {
print "<LoginResultsURL>http://$uamip:$uamport/logon?username=$username&password=$pappassword</LoginResultsURL>";
} else {
print "<LoginResultsURL>http://$uamip:$uamport/logon?username=$username&response=$response&userurl=$userurl</LoginResultsURL>";
}
print "</AuthenticationReply>
</WISPAccessGatewayParam>
-->
</html>
";
exit(0);
}


# Default: It was not a form request
$result = 0;

# If login successful
if ($res =~ /^success$/) {
$result = 1;
}

# If login failed
if ($res =~ /^failed$/) {
$result = 2;
}

# If logout successful
if ($res =~ /^logoff$/) {
$result = 3;
}

# If tried to login while already logged in
if ($res =~ /^already$/) {
$result = 4;
}

# If not logged in yet
if ($res =~ /^notyet$/) {
$result = 5;
}

# If login from smart client
if ($res =~ /^smartclient$/) {
$result = 6;
}

# If requested a logging in pop up window
if ($res =~ /^popup1$/) {
$result = 11;
}

# If requested a success pop up window
if ($res =~ /^popup2$/) {
$result = 12;
}

# If requested a logout pop up window
if ($res =~ /^popup3$/) {
$result = 13;
}


# Otherwise it was not a form request
# Send out an error message
if ($result == 0) {
print "Content-type: text/html\n\n
<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">
<html>
<head>
<title>ChilliSpot Login Failed</title>
<meta http-equiv=\"Cache-control\" content=\"no-cache\">
<meta http-equiv=\"Pragma\" content=\"no-cache\">
</head>
<body bgColor = '#c0d8f4'>
<h1 style=\"text-align: center;\">ChilliSpot Login Failed</h1>
<center>
Login must be performed through ChilliSpot daemon.
</center>
</body>
</html>
";
exit(0);
}

#Generate the output
print "Content-type: text/html\n\n
<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">
<html>
<head>
<title>ChilliSpot Login</title>
<meta http-equiv=\"Cache-control\" content=\"no-cache\">
<meta http-equiv=\"Pragma\" content=\"no-cache\">
<SCRIPT LANGUAGE=\"JavaScript\">
var blur = 0;
var starttime = new Date();
var startclock = starttime.getTime();
var mytimeleft = 0;

function doTime() {
window.setTimeout( \"doTime()\", 1000 );
t = new Date();
time = Math.round((t.getTime() - starttime.getTime())/1000);
if (mytimeleft) {
time = mytimeleft - time;
if (time <= 0) {
window.location = \"$loginpath?res=popup3&uamip=$uamip&uamport=$uamport\";
}
}
if (time < 0) time = 0;
hours = (time - (time % 3600)) / 3600;
time = time - (hours * 3600);
mins = (time - (time % 60)) / 60;
secs = time - (mins * 60);
if (hours < 10) hours = \"0\" + hours;
if (mins < 10) mins = \"0\" + mins;
if (secs < 10) secs = \"0\" + secs;
title = \"Online time: \" + hours + \":\" + mins + \":\" + secs;
if (mytimeleft) {
title = \"Remaining time: \" + hours + \":\" + mins + \":\" + secs;
}
if(document.all || document.getElementById){
document.title = title;
}
else {
self.status = title;
}
}

function popUp(URL) {
if (self.name != \"chillispot_popup\") {
chillispot_popup = window.open(URL, 'chillispot_popup', 'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=500,height=375');
}
}

function doOnLoad(result, URL, userurl, redirurl, timeleft) {
if (timeleft) {
mytimeleft = timeleft;
}
if ((result == 1) && (self.name == \"chillispot_popup\")) {
doTime();
}
if ((result == 1) && (self.name != \"chillispot_popup\")) {
chillispot_popup = window.open(URL, 'chillispot_popup', 'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=500,height=375');
}
if ((result == 2) || result == 5) {
document.form1.UserName.focus()
}
if ((result == 2) && (self.name != \"chillispot_popup\")) {
chillispot_popup = window.open('', 'chillispot_popup', 'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=400,height=200');
chillispot_popup.close();
}
if ((result == 12) && (self.name == \"chillispot_popup\")) {
doTime();
if (redirurl) {
opener.location = redirurl;
}
else if (userurl) {
opener.location = userurl;
}
else if (opener.home) {
opener.home();
}
else {
opener.location = \"about:home\";
}
self.focus();
blur = 0;
}
if ((result == 13) && (self.name == \"chillispot_popup\")) {
self.focus();
blur = 1;
}
}

function doOnBlur(result) {
if ((result == 12) && (self.name == \"chillispot_popup\")) {
if (blur == 0) {
blur = 1;
self.focus();
}
}
}
</script>
</head>
<body onLoad=\"javascript:doOnLoad($result, '$loginpath?res=popup2&uamip=$uamip&uamport=$uamport&userurl=$userurl&redirurl=$redirurl&timeleft=$timeleft','$userurldecode', '$redirurldecode', '$timeleft')\" onBlur = \"javascript:doOnBlur($result)\" bgColor = '#c0d8f4'>";


# if (!window.opener) {
# document.bgColor = '#c0d8f4';
# }

#print "THE INPUT: $input";
#foreach $key (sort (keys %ENV)) {
# print $key, ' = ', $ENV{$key}, "<br>\n";
#}

if ($result == 2) {
print "
<h1 style=\"text-align: center;\">ChilliSpot Login Failed</h1>";
if ($reply) {
print "<center> $reply </BR></BR></center>";
}
}

if ($result == 5) {
print "
<h1 style=\"text-align: center;\">ChilliSpot Login</h1>";
}

if ($result == 2 || $result == 5) {
print "
<form name=\"form1\" method=\"post\" action=\"$loginpath\">
<INPUT TYPE=\"hidden\" NAME=\"challenge\" VALUE=\"$challenge\">
<INPUT TYPE=\"hidden\" NAME=\"uamip\" VALUE=\"$uamip\">
<INPUT TYPE=\"hidden\" NAME=\"uamport\" VALUE=\"$uamport\">
<INPUT TYPE=\"hidden\" NAME=\"userurl\" VALUE=\"$userurldecode\">
<center>
<table border=\"0\" cellpadding=\"5\" cellspacing=\"0\" style=\"width: 217px;\">
<tbody>
<tr>
<td align=\"right\">Username:</td>
<td><input STYLE=\"font-family: Arial\" type=\"text\" name=\"UserName\" size=\"20\" maxlength=\"128\"></td>
</tr>
<tr>
<td align=\"right\">Password:</td>
<td><input STYLE=\"font-family: Arial\" type=\"password\" name=\"Password\" size=\"20\" maxlength=\"128\"></td>
</tr>
<tr>
<td align=\"center\" colspan=\"2\" height=\"23\"><input type=\"submit\" name=\"button\" value=\"Login\" onClick=\"javascript:popUp('$loginpath?res=popup1&uamip=$uamip&uamport=$uamport')\"></td>
</tr>
</tbody>
</table>
</center>
</form>
</body>
</html>";
}

if ($result == 1) {
print "
<h1 style=\"text-align: center;\">Logged in to ChilliSpot</h1>";

if ($reply) {
print "<center> $reply </BR></BR></center>";
}

print "
<center>
<a href=\"http://$uamip:$uamport/logoff\">Logout</a>
</center>
</body>
</html>";
}

if (($result == 4) || ($result == 12)) {
print "
<h1 style=\"text-align: center;\">Logged in to ChilliSpot</h1>
<center>
<a href=\"http://$uamip:$uamport/logoff\">Logout</a>
</center>
</body>
</html>";
}


if ($result == 11) {
print "<h1 style=\"text-align: center;\">Logging in to ChilliSpot</h1>";
print "
<center>
Please wait......
</center>
</body>
</html>";
}


if (($result == 3) || ($result == 13)) {
print "
<h1 style=\"text-align: center;\">Logged out from ChilliSpot</h1>
<center>
<a href=\"http://$uamip:$uamport/prelogin\">Login</a>
</center>
</body>
</html>";
}


exit(0);
Voltus87
Perlero nuevo
Perlero nuevo
 
Mensajes: 2
Registrado: 2011-02-02 13:42 @612

Re: Cómo detectar cuándo cierran una ventana desde el cgi

Notapor explorer » 2011-02-02 16:47 @741

Yo me refiero a esto: http://www.htmlhelp.com/reference/html40/html/body.html

Colocar una llamada a tu cgi en el evento unload(), que se dispara cuando la ventana se cierra.

Sí, hay que modificar el cgi para que tenga en cuenta ese caso.

Valdría con crear un URL en el unload() para que pusiera res a logout. Algo así: /programa.cgi?res=logout

Bueno, no sé si haría falta algo más...

Y además, si el usuario desactiva el soporte de JavaScript, el unload no funcionaría, por lo que no recibirías el aviso.

El asunto es más complejo de lo que parece... ¿Has probado a buscar por Internet por "Chillispot close popup"?
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España


Volver a Web

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 6 invitados