0

I'm using Apache2::Cookie (i.e. Apache2 with mod_perl) to parse cookies.

my %cookies = Apache2::Cookie->fetch;
do_something($cookies{"cookie1"});

This code has been running in production for years without any problems. I just learned that a cookie with particular formatting causes this to throw an exception Expected token not present. The cookie in question is generated by client-side JavaScript:

document.cookie = "val=a,b"

Apache2::Cookie appears to not like the comma.

I can catch this error with eval, but the cookie retrieval is done in lots of places in the code (yes, it could have been factored out, but frankly the code is so simple there was no need). In any case, it's there now and I have to track down and catch the exception for this cookie that I didn't set and I don't need.

Is there an easier way to get rid of this exception than refactoring dozens of calls to Apache2::Cookie->fetch? Either by redefining Apache2::Cookie::fetch, or by setting a global flag for libapreq to not puke on this (there isn't any I could find), or some other bright idea I'm missing.

Palec
  • 12,743
  • 8
  • 69
  • 138
evil otto
  • 10,348
  • 25
  • 38
  • There's probably a better way than wrapping Apache2::Cookie::fetch. Unfortunately I have no experience with the module, so I can't advice you on that, but if you want to manually wrap a sub, you could do something like `use Apache2::Cookie; BEGIN { my $orig = \&Apache2::Cookie::fetch; no warnings 'redefine'; *Apache2::Cookie::fetch = sub { eval { shift->$orig(@_) } or do { stuff } }; }` (untested, but should work, hopefully :). However, you are probably better off using something like `Class::Method::Modifiers` to get a Moose-like around modifier. – Hugmeir Nov 15 '11 at 03:33
  • @Hugmier - that approach doesn't seem to work, it just sends the apache process into an endless loop until it segfaults by exhausting all available memory. It's also not clear where I would put that code; I tried adding it to a common module where I'm already loading Apache2::Cookie – evil otto Nov 15 '11 at 20:37

2 Answers2

0

I faced the same issue and you can find the solution here :

“Expected token not present” error in my Apache log

Community
  • 1
  • 1
M-D
  • 10,247
  • 9
  • 32
  • 35
0

(yes, it could have been factored out, but frankly the code is so simple there was no need).

I would take this opportunity to fix this oversight, instead of making another

If you insist, you could learn something from CGI::Cookie

 sub fetch {
     my $class = shift;
     my $raw_cookie = get_raw_cookie(@_) or return;
     return $class->parse($raw_cookie);
 }

 sub get_raw_cookie {
   my $r = shift;
   $r ||= eval { $MOD_PERL == 2                    ? 
                   Apache2::RequestUtil->request() :
                   Apache->request } if $MOD_PERL;

   return $r->headers_in->{'Cookie'} if $r;

   die "Run $r->subprocess_env; before calling fetch()" 
     if $MOD_PERL and !exists $ENV{REQUEST_METHOD};

   return $ENV{HTTP_COOKIE} || $ENV{COOKIE};
 }
U.S.A.
  • 76
  • 1
  • How does this help? The problem isn't getting the cookie header, it's parsing the actual cookie values and throwing an error while parsing. – evil otto Nov 15 '11 at 20:39