pffan239 has asked for the wisdom of the Perl Monks concerning the following question:

I've got a custom authentication system for a CGI::Application based site where I want to store a copy of a CGI object when a inactivity timeout occurs. I've got a solution that seems to work great that does the serialization with FreezeThaw, except when the CGI object results from a POST submission with a file upload field where it dies with error "Do not know how to thaw GLOB at /usr/lib/perl5/site_perl/5.8.6/FreezeThaw.pm line 505".

I'm guessing that FreezeThaw is barfing on the globs that the CGI module uses references the uploaded files. This kinda makes sense to me. If you've already got something in file, why bother trying to serialize a pointer to it?

I remembered that the CGI module had a method for saving state (save_parameters), but after testing it out, I noted that it doesn't do anything for upload files (the name of the upload file is preserved; not the content.)

Unless an esteemeed monk (with XP far greater than me!) has an alternative approach, I'll probably go under the hood of the CGI module and figure out how to save copies of the uploaded files myself and recreate pointers to them when I restore the CGI object again in the future.

Am I overlooking a simpler solution?

Thanks for any help!

  • Comment on Suggestion- How to serialize a cgi object?

Replies are listed 'Best First'.
Re: Suggestion- How to serialize a cgi object?
by pc88mxer (Vicar) on May 09, 2008 at 18:11 UTC
    The GLOB is an open file handle, and there's no way to serialize that. i think you are going to have to come up with your own serialization procedure wrapped around FreezeThaw, like storing the data you want to save (including the contents of the uploaded files) into a hash and then using FreezeThaw to save that to a file.

    I'm very curious what you are trying to accomplish with this. Implicit with a CGI object is the connection (through STDIN and STDOUT) it has with the web server, and there's no way to restore that. Can you describe how this would work?

      After the CGI object parses the GET or POST, its all jammed in the CGI object's internal data structure (except for the file uploads of course, which are referenced by the globs.) Freezing the CGI object and thawing it back later seems to work fine for me in my experience.

Re: Suggestion- How to serialize a cgi object?
by pc88mxer (Vicar) on May 10, 2008 at 06:43 UTC
    The more I contemplate this, the more I think what you are really looking for is the ability to store session data or user data. Are you using any kind of session management right now? Do you require users to log in?

    If not, here's how things could work if you implemented users and user data: When users visited your site they would log in and receive a cookie identifying who they are (their login id). When they uploaded a file, those files would be placed in a directory identified by their login id. When they later visited your site, you can retrieve those files by getting their login id from the login cookie and consulting the appropriate directory. You can store other data (such as POST data) using the FreezeThaw module, but I still would transfer only the data you really need to save (i.e. the parameter data) to a new hash and serialize that to a file instead of serializing the entire CGI object.

    Am I on the right track here? If so, there are a lot of modules to help you manage web sessions. For instance, have a look at CGI::Session.

      pc88mxer, belated thanks for the first follow up.

      Yes, users need to log in. I'm already using CGI::Session (via CGI::Application::Plugin::Session) to manage sessions. I'm using a session variable with expiration to keep track of their activity and time them out after certain period of time.

      Here's what I'm trying to accomplish, in short... when a user's login goes inactive and they try to continue by clicking a link or submitting a form, I want to capture all the request details (ie, everything in the CGI object at the time), store it, prompt the user to reauthenticate, and then (after successful re-authentication) play back the original request using the stored request details. The whole goal is to prevent to user from losing data in form that may take a while to file in. Pretty reasonable?

      I've actually got everything that worked out except for when the CGI object to be stored is from a POST that happened to have a file upload field.

      I think your suggestion to store the actual POST data directly or save off the files manually (keyed by session_id) is where was headed originally. I was just wondering if I was missing something simpler. Been working on this stuff for a while, so I was afraid that I might be missing something obvious.

      I'm not sure which of these two alternatives I like better:

      1. If I store the actual POST data, I need to have separate routines to handle GETs and POSTs (serializing the CGI object added a nice layer of abstraction.) Getting the saved POST data back into a new CGI object is also a little tricky (but do able).
      2. Scanning through the incoming CGI to save off files manually isn't difficult. Probably have to do something tricky to get files back into the CGI when its restored later. I'm pretty sure you can't do something like $cgi->param('uploadFieldName',$pathToFile). that would be way too easy.