Main Page |
Recipe 21.10 Transparently Storing Information in URLs21.10.1 ProblemYou want to store information like session IDs in the URL, but you don't want to figure out to how work around the extra data when constructing relative URLs. 21.10.2 SolutionStore the ID at the start of the URL: http://www.example.com/ID/12345678/path/to/page Extract it with a PerlTransHandler, and store it in a pnote, a hash entry accessible by other Perl handlers in this request: sub trans { my $r = shift; my $uri = $r->uri( ); if ($uri =~ s{/ID/(\d{8})}{ }) { $r->pnotes("ID", $1); } $r->uri($uri); return DECLINED; } Restore the URL in a PerlFixupHandler: sub fixup { my $r = shift; my $id = $r->pnotes("ID"); if ($id) { $r->uri("/ID/$id" . $r->uri); } return DECLINED; } Consult the pnote in the content handler: use Apache::URI; sub content { my $r = shift; my $id = $r->pnotes("ID"); unless ($id) { join(('', map { int rand 10 } (1..8)); my $uri = Apache::URI->parse($r); $uri->path("ID/$id" . $uri->path); $r->header_out(Location => $uri->unparse); return REDIRECT; } # use $id return OK; } 21.10.3 DiscussionThe client thinks your pages have a URL like http://www.example.com/ID/12345678/path/to/page.html. Your PerlTransHandler intercepts the incoming request and removes the /ID/12345678 part before Apache tries to translate the request into a file location. Just before your content handler runs, your PerlFixupHandler reinserts the ID. When your content handler calls $r->uri, it gets a URI that includes the ID. We returned DECLINED from our PerlTransHandler and PerlFixupHandler to indicate that any other translation or fixup handlers that were installed should also be run. If we returned OK in the PerlTransHandler, Apache would not call any subsequent translation handlers. In PerlFixupHandlers, DECLINED and OK both mean a successful fixup, and that other fixup handlers should also run. This solution doesn't look at the HTML emitted by your handler, so it only preserves the ID across relative links. If you give absolute links in your HTML (HREF="/elsewhere/"), then you'll lose the ID and have to re-establish it. 21.10.4 See AlsoRecipe 12.3 of mod_perl Developer's Cookbook; Recipe 21.11 |
Main Page |