Managing "sessions" for each open browser window
Hello, Another implementation question for my planned web-site: I want to maintain a "session" (i.e. collection of server-side variables) for each open browser window (not browser "session" in the technical sense). Use-case: 1. a user open a new browser window/tab, goes to my web-site. 2. user changes settings, does some stuff, information is stored for this "session" of open window. 3. same user, same browser, opens a new window/tab, goes (again) to my web-site - now gets a new "empty" session. 4. user changes settings, does some stuff, information is stored for this "session" of open window. 5. the two browser windows (from step 2,4) can be viewed side-by-side, each maintaining independent set of session information. Implementation-wise, I've seen similar web-sites assign a new CGI variable when a user visits the "root" (=landing) page, and propagate that variable in every generated link or HTML form. e.g.: 1. user visits http://myserver.com 2. user redirected to http://myserver.com/?session_id=5 3. from now on, every URL (generated by Dancer's templates) will carry the session ID. 4. if the user opens a new (empty) tab and visists "http://myserver.com" again, he will get "session_id=6" for that window. This seems reasonably easy to implement, but how do I connect the CGI session variable to some sort of Dancer's "session" keyword? I'm thinking of some "before" hook mechanism, but not sure how to go about it... Any suggestions are welcomed, -gordon P.S, I'm aware that a mischievous user could copy&paste the URL to another window, and have two open windows changing the same "session" - I'm not worried by this scenario (as users will be explained that such a thing will simply interfere with their work).
Hello (again), A slightly more technical question regarding session management: Assaf Gordon wrote, On 09/24/2012 01:48 PM:
I want to maintain a "session" (i.e. collection of server-side variables) for each open browser window (not browser "session" in the technical sense).
[...]
This seems reasonably easy to implement, but how do I connect the CGI session variable to some sort of Dancer's "session" keyword? I'm thinking of some "before" hook mechanism, but not sure how to go about it...
The session engine and abstraction are only for the server side (session storage, as YAML / memory/ db / etc.). I want to change the client-side mechanism (i.e. not to use a cookie, but a CGI variable). 1. Can I override "Dancer::Session::Abstract::write_session_id()" (even though the comment above says "Methods below this this line should not be overloaded" :) ) ? or is there a better way ? 2. Does Dancer2 offer a cleaner method, and should I use it for a website that should be ready in 3 months? Thanks, -gordon
Hello (yet again), On 09/27/2012 11:15 AM, Assaf Gordon wrote:
Assaf Gordon wrote, On 09/24/2012 01:48 PM:
I want to maintain a "session" (i.e. collection of server-side variables) for each open browser window (not browser "session" in the technical sense).
I implemented such a mechanism as a Dancer Plugin: Dancer::Plugin::WindowSession . See it in action here: http://winsid.cancan.cshl.edu/ The source code for the plugin (and the demo) are here: https://github.com/agordon/Dancer-Plugin-WindowSession (and soon in CPAN). On the Perl side, simply use "window_session" keyword instead of "session" keyword. On the template side, you'll need to pass along the "winsid" (=window session id) as a CGI parameter to every URL and POST request. See code example here (that's the method that generates the plot for the demo): https://github.com/agordon/Dancer-Plugin-WindowSession/blob/master/eg/exampl... It uses the same session mechanism defined in the config.yml, and only uses standard Dancer keywords (no ugly hacking), so I hope it will be stable and portable for Dancer2 . Comments are welcomed, -gordon
This is interesting work. I wish I had more time to delve into it. On Fri, Sep 28, 2012 at 3:49 AM, Assaf Gordon <gordon@cshl.edu> wrote:
Hello (yet again),
On 09/27/2012 11:15 AM, Assaf Gordon wrote:
Assaf Gordon wrote, On 09/24/2012 01:48 PM:
I want to maintain a "session" (i.e. collection of server-side variables) for each open browser window (not browser "session" in the technical sense).
I implemented such a mechanism as a Dancer Plugin: Dancer::Plugin::WindowSession .
See it in action here: http://winsid.cancan.cshl.edu/
The source code for the plugin (and the demo) are here: https://github.com/agordon/**Dancer-Plugin-WindowSession<https://github.com/agordon/Dancer-Plugin-WindowSession> (and soon in CPAN).
On the Perl side, simply use "window_session" keyword instead of "session" keyword. On the template side, you'll need to pass along the "winsid" (=window session id) as a CGI parameter to every URL and POST request.
See code example here (that's the method that generates the plot for the demo): https://github.com/agordon/**Dancer-Plugin-WindowSession/** blob/master/eg/example/lib/**window_session_test.pm#L28<https://github.com/agordon/Dancer-Plugin-WindowSession/blob/master/eg/example/lib/window_session_test.pm#L28>
It uses the same session mechanism defined in the config.yml, and only uses standard Dancer keywords (no ugly hacking), so I hope it will be stable and portable for Dancer2 .
Comments are welcomed,
-gordon
______________________________**_________________ Dancer-users mailing list Dancer-users@perldancer.org http://www.backup-manager.org/**cgi-bin/listinfo/dancer-users<http://www.backup-manager.org/cgi-bin/listinfo/dancer-users>
This is really great ! Is it already on CPAN ? It's a very useful Plugin. Le vendredi 28 septembre 2012 à 03:49, Assaf Gordon a écrit :
Hello (yet again),
On 09/27/2012 11:15 AM, Assaf Gordon wrote:
Assaf Gordon wrote, On 09/24/2012 01:48 PM:
I want to maintain a "session" (i.e. collection of server-side variables) for each open browser window (not browser "session" in the technical sense).
I implemented such a mechanism as a Dancer Plugin: Dancer::Plugin::WindowSession .
See it in action here: http://winsid.cancan.cshl.edu/
The source code for the plugin (and the demo) are here: https://github.com/agordon/Dancer-Plugin-WindowSession (and soon in CPAN).
On the Perl side, simply use "window_session" keyword instead of "session" keyword. On the template side, you'll need to pass along the "winsid" (=window session id) as a CGI parameter to every URL and POST request.
See code example here (that's the method that generates the plot for the demo): https://github.com/agordon/Dancer-Plugin-WindowSession/blob/master/eg/exampl...
It uses the same session mechanism defined in the config.yml, and only uses standard Dancer keywords (no ugly hacking), so I hope it will be stable and portable for Dancer2 .
Comments are welcomed, -gordon
_______________________________________________ Dancer-users mailing list Dancer-users@perldancer.org (mailto:Dancer-users@perldancer.org) http://www.backup-manager.org/cgi-bin/listinfo/dancer-users
Damien Krotkine wrote, On 09/29/2012 03:33 PM:
This is really great ! Is it already on CPAN ? It's a very useful Plugin.
Thanks. First version is available in CPAN: https://metacpan.org/module/Dancer::Plugin::WindowSession
Can you try to make it work with Dancer2 ? If you need it we can help you making it compliant On 1 October 2012 15:09, Assaf Gordon <gordon@cshl.edu> wrote:
Damien Krotkine wrote, On 09/29/2012 03:33 PM:
This is really great ! Is it already on CPAN ? It's a very useful Plugin.
Thanks.
First version is available in CPAN: https://metacpan.org/module/Dancer::Plugin::WindowSession
damien krotkine wrote, On 10/01/2012 09:22 AM:
Can you try to make it work with Dancer2 ? If you need it we can help you making it compliant
Trying to run the example website with Dancer2 gives: === $ cd ./Dancer-Plugin-WindowSession/eg/example $ perl -I/home/gordon/sources/Dancer2/lib/ bin/app.pl Eval went very, very wrong: # localizing: Dancer::Core::Role::Session::id, Dancer::Core::Role::Engine::type, Dancer::Core::Role::Engine::context, Dancer::Core::Role::Engine::config, Dancer::Core::Role::Session::data, Dancer::Core::Role::Session::name, Dancer::Core::Role::Session::session_secure, Dancer::Core::Role::Session::session_is_http_only, Dancer::Core::Role::Session::session_expires, Dancer::Session::YAML::new { my $isa_check_for_id = ${$_[1][0]->{"\$isa_check_for_id"}}; no warnings 'closure'; sub Dancer::Core::Role::Session::id { (@_ > 1 ? do { my ($self, $value) = @_; $isa_check_for_id->($value); $self->{"id"} = $value; } : do { $_[0]->{"id"} = $_[0]->_build_id unless exists $_[0]->{"id"}; $_[0]->{"id"} } ) } $Sub::Quote::QUOTED{"CODE(0x18808b8)"}[3] = \&Dancer::Core::Role::Session::id } ... ... ... [ and the list goes on and on and on until: ] Number found where operator expected at (eval 89) line 18, near "->1" BEGIN failed--compilation aborted at bin/app.pl line 2. === Not sure even where to start fixing this...
On 10/01/2012 08:54 PM, Assaf Gordon wrote:
damien krotkine wrote, On 10/01/2012 09:22 AM:
Can you try to make it work with Dancer2 ? If you need it we can help you making it compliant
Trying to run the example website with Dancer2 gives: === $ cd ./Dancer-Plugin-WindowSession/eg/example $ perl -I/home/gordon/sources/Dancer2/lib/ bin/app.pl Eval went very, very wrong:
# localizing: Dancer::Core::Role::Session::id, Dancer::Core::Role::Engine::type, Dancer::Core::Role::Engine::context, Dancer::Core::Role::Engine::config, Dancer::Core::Role::Session::data, Dancer::Core::Role::Session::name, Dancer::Core::Role::Session::session_secure, Dancer::Core::Role::Session::session_is_http_only, Dancer::Core::Role::Session::session_expires, Dancer::Session::YAML::new { my $isa_check_for_id = ${$_[1][0]->{"\$isa_check_for_id"}}; no warnings 'closure'; sub Dancer::Core::Role::Session::id { (@_> 1 ? do { my ($self, $value) = @_; $isa_check_for_id->($value); $self->{"id"} = $value; } : do { $_[0]->{"id"} = $_[0]->_build_id unless exists $_[0]->{"id"}; $_[0]->{"id"} } ) } $Sub::Quote::QUOTED{"CODE(0x18808b8)"}[3] = \&Dancer::Core::Role::Session::id } ... ... ... [ and the list goes on and on and on until: ] Number found where operator expected at (eval 89) line 18, near "->1" BEGIN failed--compilation aborted at bin/app.pl line 2. ===
Not sure even where to start fixing this...
Please try to use plugin_args inside your plugin (see Dancer::Plugin for more information). Regards Racke -- LinuXia Systems => http://www.linuxia.de/ Expert Interchange Consulting and System Administration ICDEVGROUP => http://www.icdevgroup.org/ Interchange Development Team
Stefan Hornburg (Racke) wrote, On 10/01/2012 03:29 PM:
On 10/01/2012 08:54 PM, Assaf Gordon wrote:
Trying to run the example website with Dancer2 gives: === $ cd ./Dancer-Plugin-WindowSession/eg/example $ perl -I/home/gordon/sources/Dancer2/lib/ bin/app.pl Eval went very, very wrong: [ and the list goes on and on and on until: ] Number found where operator expected at (eval 89) line 18, near "->1" BEGIN failed--compilation aborted at bin/app.pl line 2. ===
Not sure even where to start fixing this...
Please try to use plugin_args inside your plugin (see Dancer::Plugin for more information).
I don't think it's a runtime problem (parsing parameters of my subs) - this errors happens during compilation (perhaps because some of the config parsing happens during compilation in some "BEGIN" block? I seem to remember encountering similar annoyances with Dancer 1 when there were problems in the config file). Anyway, trying with "perl -d" shows the following stack-trace even before showing the debug prompt. Maybe you'll spot something obvious that I missed... === [... lots of messages ... ] called at /usr/local/share/perl/5.14.2/Sub/Quote.pm line 5 Sub::Quote::_clean_eval('local *Dancer::Core::Role::Engine::config;\x{a}local *Dancer::Cor...', 'ARRAY(0x2a3ed20)') called at /usr/local/share/perl/5.14.2/Sub/Quote.pm line 95 Sub::Quote::_unquote_all_outstanding() called at /usr/local/share/perl/5.14.2/Sub/Quote.pm line 137 Sub::Quote::unquote_sub('CODE(0x3441f98)') called at /usr/local/share/perl/5.14.2/Method/Generate/Constructor.pm line 32 Method::Generate::Constructor::__ANON__[/usr/local/share/perl/5.14.2/Method/Generate/Constructor.pm:35]() called at /usr/local/share/perl/5.14.2/Sub/Defer.pm line 16 Sub::Defer::undefer_sub('CODE(0x3439ed8)') called at /usr/local/share/perl/5.14.2/Sub/Defer.pm line 38 Sub::Defer::__ANON__[/usr/local/share/perl/5.14.2/Sub/Defer.pm:39]('Dancer::Session::YAML', 'environment', 'development', 'location', '/home/gordon/projects/Dancer-Plugin-WindowSession/eg/example/...', 'postponed_hooks', 'HASH(0x2e995a8)', 'session_dir', '/home/gordon/projects/Dancer-Plugin-WindowSession/eg/example/...', ...) called at /home/gordon/sources/Dancer2/lib//Dancer/Factory/Engine.pm line 19 Dancer::Factory::Engine::create('Dancer::Factory::Engine', 'session', 'YAML', 'environment', 'development', 'location', '/home/gordon/projects/Dancer-Plugin-WindowSession/eg/example/...', 'session_dir', '/home/gordon/projects/Dancer-Plugin-WindowSession/eg/example/...', ...) called at /home/gordon/sources/Dancer2/lib//Dancer/Core/Role/Config.pm line 211 Dancer::Core::Role::Config::__ANON__[/home/gordon/sources/Dancer2/lib//Dancer/Core/Role/Config.pm:214]('Dancer::Core::Runner=HASH(0x2e83198)', 'YAML', 'HASH(0x2f291b8)') called at /home/gordon/sources/Dancer2/lib//Dancer/Core/Role/Config.pm line 266 Dancer::Core::Role::Config::_compile_config_entry('Dancer::Core::Runner=HASH(0x2e83198)', 'session', 'YAML', 'HASH(0x2f291b8)') called at /home/gordon/sources/Dancer2/lib//Dancer/Core/Role/Config.pm line 154 Dancer::Core::Role::Config::_compile_config('Dancer::Core::Runner=HASH(0x2e83198)', 'HASH(0x2f291b8)') called at /home/gordon/sources/Dancer2/lib//Dancer/Core/Role/Config.pm line 122 Dancer::Core::Role::Config::_build_config('Dancer::Core::Runner=HASH(0x2e83198)') called at (eval 23)[(eval 22)[/usr/local/share/perl/5.14.2/Sub/Quote.pm:5]:29] line 44 Dancer::Core::Role::Config::config('Dancer::Core::Runner=HASH(0x2e83198)') called at /home/gordon/sources/Dancer2/lib//Dancer.pm line 67 Dancer::import('Dancer') called at bin/app.pl line 2 main::BEGIN() called at (eval 92)[(eval 91)[/usr/local/share/perl/5.14.2/Sub/Quote.pm:5]:11] line 31 eval {...} called at (eval 92)[(eval 91)[/usr/local/share/perl/5.14.2/Sub/Quote.pm:5]:11] line 31 at /usr/local/share/perl/5.14.2/Sub/Quote.pm line 96 Sub::Quote::_unquote_all_outstanding() called at /usr/local/share/perl/5.14.2/Sub/Quote.pm line 137 Sub::Quote::unquote_sub('CODE(0x3441f98)') called at /usr/local/share/perl/5.14.2/Method/Generate/Constructor.pm line 32 Method::Generate::Constructor::__ANON__[/usr/local/share/perl/5.14.2/Method/Generate/Constructor.pm:35]() called at /usr/local/share/perl/5.14.2/Sub/Defer.pm line 16 Sub::Defer::undefer_sub('CODE(0x3439ed8)') called at /usr/local/share/perl/5.14.2/Sub/Defer.pm line 38 Sub::Defer::__ANON__[/usr/local/share/perl/5.14.2/Sub/Defer.pm:39]('Dancer::Session::YAML', 'environment', 'development', 'location', '/home/gordon/projects/Dancer-Plugin-WindowSession/eg/example/...', 'postponed_hooks', 'HASH(0x2e995a8)', 'session_dir', '/home/gordon/projects/Dancer-Plugin-WindowSession/eg/example/...', ...) called at /home/gordon/sources/Dancer2/lib//Dancer/Factory/Engine.pm line 19 Dancer::Factory::Engine::create('Dancer::Factory::Engine', 'session', 'YAML', 'environment', 'development', 'location', '/home/gordon/projects/Dancer-Plugin-WindowSession/eg/example/...', 'session_dir', '/home/gordon/projects/Dancer-Plugin-WindowSession/eg/example/...', ...) called at /home/gordon/sources/Dancer2/lib//Dancer/Core/Role/Config.pm line 211 Dancer::Core::Role::Config::__ANON__[/home/gordon/sources/Dancer2/lib//Dancer/Core/Role/Config.pm:214]('Dancer::Core::Runner=HASH(0x2e83198)', 'YAML', 'HASH(0x2f291b8)') called at /home/gordon/sources/Dancer2/lib//Dancer/Core/Role/Config.pm line 266 Dancer::Core::Role::Config::_compile_config_entry('Dancer::Core::Runner=HASH(0x2e83198)', 'session', 'YAML', 'HASH(0x2f291b8)') called at /home/gordon/sources/Dancer2/lib//Dancer/Core/Role/Config.pm line 154 Dancer::Core::Role::Config::_compile_config('Dancer::Core::Runner=HASH(0x2e83198)', 'HASH(0x2f291b8)') called at /home/gordon/sources/Dancer2/lib//Dancer/Core/Role/Config.pm line 122 Dancer::Core::Role::Config::_build_config('Dancer::Core::Runner=HASH(0x2e83198)') called at (eval 23)[(eval 22)[/usr/local/share/perl/5.14.2/Sub/Quote.pm:5]:29] line 44 Dancer::Core::Role::Config::config('Dancer::Core::Runner=HASH(0x2e83198)') called at /home/gordon/sources/Dancer2/lib//Dancer.pm line 67 Dancer::import('Dancer') called at bin/app.pl line 2 main::BEGIN() called at bin/app.pl line 2 eval {...} called at bin/app.pl line 2 BEGIN failed--compilation aborted at bin/app.pl line 2. at bin/app.pl line 2 Debugged program terminated. Use q to quit or R to restart, use o inhibit_exit to avoid stopping after program termination, h q, h R or h o to get additional info. DB<1> ===
participants (5)
-
Assaf Gordon -
Damien Krotkine -
damien krotkine -
sawyer x -
Stefan Hornburg (Racke)