http://www.perlmonks.org?node_id=968362


in reply to CGI::Session keeps re-using same session ID

What am I doing wrong? Thx.

:) For some unknown reason you're trying to reinvent the wheel, but if you insist, see Cookie login (pseudocode)/ http://www.stonehenge.com/merlyn/WebTechniques/ / Basic cookie management (May 01),

For easier ways see cgi-app / mojo / dancer / catalyst / https://metacpan.org/module/Dancer::Tutorial / RFC: Proposed tutorial - simple login script using CGI::Application,CGI::Application - LoginLogoutExampleApp / CGI::Application::Plugin::Authentication::Display::Classic - login box that works out of the box

  • Comment on Re: CGI::Session keeps re-using same session ID

Replies are listed 'Best First'.
Re^2: CGI::Session keeps re-using same session ID
by alain_desilets (Beadle) on May 02, 2012 at 12:21 UTC

    Thx for the tips. I'm not one to reinvent the wheel. I have spent the last 48 hours looking for an easy way to do sessions and mostly what I find are things like the documentation and tutorials for CGI::Session and Apache::Session, all of which seem to be very barebone.

    I did find out about CGI::Application, but I'm reluctant to use it for two reasons:

    a) CGI::Application assumes that the HTML for a transaction gets accumulated into a scalar string, and then printed all at once at the end. My application can't afford to do that, because it is a search engine that typically takes 2 minutes to complete the search. It can't afford to wait those two minutes before displaying some results. Instead, it needs to display each search result as soon as it finds it. Maybe I could inherit from CGI::Application and inject a hook into it for printing html as soon as it gets generated, but that sounds like it would be very involved.

    b) I already have a large application to which I need to add session support. I would have to do a major rewrite to cast it into the CGI::Application framework.

    I'll look at some of the other links you provided, and hopefully I'll find what I need there. Alain

      I did find out about CGI::Application, but I'm reluctant to use it for reason a

      To stream from CGI::Application see the docs, search for "stream", it also links the practical example CGI::Application::Plugin::Stream. Basically, in your target runmode, print the headers immediately, signal CGI::Application not to print any headers when the runmode returns, and then just prints the content one chunk at a time, and return nothing.

        CGI::Application::Plugin::Streaming does not really provide what I need. I am not trying to stream a static file from disk. Instead, I am trying to write a run mode that dynamically generates HTML content and display each line of this dynamically generated content as soon as it becomes available.

        But your post inspired me to try the following hack: stream the content of a temporary file, and print the dynamically generated HTML lines to that temp file.

        It doesn't seem to work, as illustrated by the following piece of code:

        #!perl # ########################################################### # This script is an attempt at creating a cgiapp run mode # that dynamically generates HTML lines, and displays them # as soon as they are available. This in contrast # to the standard cgiapp mode where the HTML content is # returned in bulk by the run mode, and cgiapp prints it # all in one go, at the very end of the transaction. # # This particular attempt uses the CGI::Application::Plugin::Streaming # plugin to stream the dynamically created content to STDOUT. # # It's implemented by the stream_dynamic_html() method, which # does the following: # # - Opens a temporary HTML file # - invokes the stream_file() method on it # - Prints the dynamically generated HTML content to the temp file # - Closes the file. # # As it turns out, this does not work for two reasons # # a) Invoking stream_file() on a file that is still open # and being written to does not work. Instad of # receiving an HTML file with the content, the browser # receives the streammed content as a text file # which only contains the single digit 1. If I try to # write the complete HTML content to the temp file, # then close it and start the file_stream(), # then I get the full HTML content, but this content # is not being displayed as you go. It only becomes # available in bulk at the end of the transaction. # # b) stream_file() does not actually display the HTML # file's content as a page. Instead, it sends it to the # browser as a "file" to be saved to disk or opened with # an appropriate application # # To try the code: # - Create a script cgiapp_streaming_with_authentication.cgi which # runs the CgiappStreamingWithAuthentication app. # - Set $fpath_to_stream and $temp_dynamic_html_fpath # to pathes on your system, which can be written to by # your web server. # - Clear cookies # - Load cgiapp_streaming_with_authentication in your # browser # - Login as u=guest, p=1234 # - Click on the 'Stream static file' link # => This will download a text file and ask you to save it # to disk, or open it. # - Click on 'Stream dynamic HTML page' link. # => - This will download a file called # streamed_dynamic_content.html # (whose content is generated dynamically), and ask # you to save it to disk, or open it. # - Notice how it takes a few seconds before it # prompts you to open or save the file (because # the script that generates the HTML content sleeps # for one second after each line it prints to the # temp file). # # - Notice how the file does not contain the HTML code # generated by stream_dynamic_html(). It only # contains the single digit 1. ########################################################### use strict; use warnings; package CgiappStreamingWithAuthentication; use base 'CGI::Application'; my $script_name = 'cgiapp_streaming_with_authentication.cgi'; my $fpath_to_stream = '/hello.txt'; my $file_type = 'text/plain'; my $temp_dynamic_html_fpath = '/streamed_dynamic_content.html'; use CGI::Application::Plugin::Stream (qw/stream_file/); my $use_authentication = 1; if ($use_authentication) { use CGI::Application::Plugin::Authentication; CgiappStreamingWithAuthentication->authen->config( DRIVER => [ 'Generic', { guest => '1234'} ], POST_LOGIN_RUNMODE => 'welcome', LOGOUT_RUNMODE => "logout" ); CgiappStreamingWithAuthentication->authen->protected_runmodes(':al +l'); } sub setup { my $self = shift; $self->start_mode('welcome'); $self->run_modes( 'welcome' => "welcome", 'stream_static_file' => "stream_static_file", 'stream_dynamic_html' => "stream_dynamic_html", ); $self->mode_param('dlg'); } sub stream_dynamic_html { my ($self) = @_; $| = 1; open TEMP_HTML_FILE, ">$temp_dynamic_html_fpath"; my $q = $self->query(); print TEMP_HTML_FILE $q->start_html(-title => 'HTML page dynamical +ly streamed to scean'); print TEMP_HTML_FILE $q->h3('HTML page dynamically streamed to sce +an'); print TEMP_HTML_FILE $q->p("The following lines will be printed at + 1 sec interval."); for (my $ii=0; $ii<3; $ii++) { print TEMP_HTML_FILE $q->p("This is line $ii.\n"); sleep(1); } print TEMP_HTML_FILE $q->p()."\n"; print TEMP_HTML_FILE "<a href=\"$script_name?dlg=stream_dynamic_ht +ml\">Stream dynamic HTML page</a><br/>\n"; print TEMP_HTML_FILE "<a href=\"$script_name?dlg=stream_static_fil +e\">Stream static file</a><br/>\n"; print TEMP_HTML_FILE $q->end_html(); close TEMP_HTML_FILE; $self->stream_file($temp_dynamic_html_fpath, 10); } sub stream_static_file { my ($self) = @_; $| = 1; $self->stream_file( $fpath_to_stream, 10); } sub welcome { my $self = shift; # Get CGI query object my $q = $self->query(); my $output = ''; $output .= $q->start_html(-title => 'Welcome to CgiappStreamingWi +thAuthentication!'); my $user_name = $self->authen->username; $output .= $q->h3("Hello, '$user_name'"); $output .= $q->p()."\n"; $output .= "<a href=\"$script_name?dlg=stream_dynamic_html\">Str +eam dynamic HTML page</a><br/>\n"; $output .= "<a href=\"$script_name?dlg=stream_static_file\">Stre +am static file</a><br/>\n"; $output .= $q->end_html(); return $output; } 1;