Re: method handlers and push_handlers / set_handlers
Stas Bekman wrote: Tim Noll wrote: Is there a proper way to call a method handler using either push_handlers or set_handlers? They both appear to call all handler refs just like normal subs, with no class name passed in. It appears that enclosing the handler in an anonymous sub is a workaround, but I was wondering if there was a better solution. # does not call handler as a method $r-push_handlers( PerlHandler = \Apache::Test::handler ); # does call handler as a method $r-push_handlers( PerlHandler = sub { Apache::Test-handler } ); See http://perl.apache.org/guide/config.html#Perl_Method_Handlers, the eagle and cookbook books. PERL_METHOD_HANDLERS=1 + $$ prototype for Apache::Test::handler My question was really about the proper way to call method handlers from either push_handlers or set_handlers since the normal technique (first example above) calls them as normal subs, i.e. the first parameter is not the class name. The second example, however, seems to do the trick. I just wanted to know whether there was a better technique and/or any pitfalls to this technique. While searching around the web a bit more today, I came across the example below from the mod_perl_method_handlers man page, which seems to be similar, so I guess I'm on the right track. However, any comments would still be appreciated. snip $r-push_handlers(PerlHandler = sub { my $r = shift; $self-perl_handler_method($r); } ); /snip -Tim
Use of uninitialized value. with no line number in error log
I know this is a pretty generic question, but if nobody knows a quick answer, I can get more specific in a later post. Under Apache 1.3.22 / mod_perl 1.26, even while using $SIG{__WARN__} = \Carp::cluck, I keep getting Use of uninitialized value. in the Apache error log, with absolutely no line number or back trace or anything else. Does anybody know what might cause this? Thanks. -Tim
method handlers and push_handlers / set_handlers
Is there a proper way to call a method handler using either push_handlers or set_handlers? They both appear to call all handler refs just like normal subs, with no class name passed in. It appears that enclosing the handler in an anonymous sub is a workaround, but I was wondering if there was a better solution. # does not call handler as a method $r-push_handlers( PerlHandler = \Apache::Test::handler ); # does call handler as a method $r-push_handlers( PerlHandler = sub { Apache::Test-handler } ); -Tim
Re: Use of uninitialized value. with no line number in error log
Stas Bekman wrote: I know this is a pretty generic question, but if nobody knows a quick answer, I can get more specific in a later post. Under Apache 1.3.22 / mod_perl 1.26, even while using $SIG{__WARN__} = \Carp::cluck, I keep getting Use of uninitialized value. in the Apache error log, with absolutely no line number or back trace or anything else. Does anybody know what might cause this? Thanks. Where did you set $SIG{__WARN__}? Try in startup.pl as early as possible. It's set in startup.pl, which is basically a modified version of the example from perl.apache.org/guide. It works beautifully for every other error I've come across, which is why this one is so curious. As I mention in my earlier follow-up to my own post, I eventually traced the problem to an incorrect driver string in DBI-connect. However, that doesn't explain (to me anyway) why I wasn't getting more detail in the error log. Perhaps I'll delve into DBI.pm, unless someone can explain this to me beforehand. -Tim
Re: method handlers and push_handlers / set_handlers
Tim Noll wrote: I know this is a pretty generic question, but if nobody knows a quick answer, I can get more specific in a later post. Under Apache 1.3.22 / mod_perl 1.26, even while using $SIG{__WARN__} = \Carp::cluck, I keep getting Use of uninitialized value. in the Apache error log, with absolutely no line number or back trace or anything else. Does anybody know what might cause this? Thanks. OK, in answer to my own question, after embedding debug statements all over my code, I found the source of my problem: After finally moving this project from Win2K to Debian, I neglected to update the driver string in DBI-connect. How embarassing ... :-( In any case, this still leaves the question: Why was there no line number or back trace in the error log? -Tim
Re: [Templates] problems with mod_perl example from Template Toolkit tutorial
Tim Noll wrote: As an alternative, I have used a PerlFixupHandler that detects a MIME type of text/html and for only those enables Mason leaving the rest alone. This lets autoindexing still work properly, as well as images and other content in the same directory. The same trick can work with Template. The code looks like this: I actually tried something like this after seeing it in one of your Web Techniques columns. Unfortunately, the content_type for anything in this Location is returning empty. As far as I can tell, because I'm using a Location directive but no Alias, Apache splits the URI between the directory and the file name, and thus looks at the directory when it tries to determine the filename and content_type, but puts the actual file name into path_info. That means that not only is there no corresponding file, but there's no extension on what Apache thinks is the file name, so it can't determine the content type. On the other hand, if I use an Alias directive and map that URI to the actual location of the template files, then Apache *can* determine the content_type. However, that eliminates the path_info that I was using as the file name in Template-process. Of course, I could always use filename instead of path_info, but that goes against Template's default rejection of absolute paths, which I assume is there for security reasons. Have I configured something wrong? Is this an issue only on Windows? I can now report that, having finally moved this project from Win2K to Debian, this problem has gone away. I haven't tested it rigorously enough to know whether it's really a Windows-only issue, but it's certainly gone now. Sorry to have bothered the Template list with this issue -- it's definitely a mod_perl thing. -Tim P.S. Hmmm ... this is my second reply to one of my own posts today ... maybe it's time for some sleep ...
Re: image corruption
First of all, let me apologize for the hacked-up code I sent with my original post. I was actually trying to return my current code back to something that looked more like the TT sample code, but I clearly didn't do a very good job. (In my actual code, I've moved $r-send_http_header() until after the $template-process() call so that I can trap file not found errors.) In any case, thanks to David Ranney. Adding this to my config file does the trick: Alias /tt/images /usr/local/apache/tt/html/images Location /tt/images SetHandler default-handler /Location Thanks. -Tim - Original Message - From: Lyle Brooks [EMAIL PROTECTED] To: Tim Noll [EMAIL PROTECTED] Cc: Lyle Brooks [EMAIL PROTECTED]; [EMAIL PROTECTED] Sent: Tuesday, February 05, 2002 5:54 PM Subject: Re: image corruption Ok, a couple of things... 1) You want to move the $r-send_http_header; call up before calling $template-process(); 2) Modify $template-process( $file, $vars, $r) to $template-process( $file, $vars) since you specify OUTPUT = $r when you create the Template object (so it's re-dundant). 3) get rid of the $r-print( $output ) line as well, $template-process() is going to send the output to Apache the way you have it setup. 4) As David Ranney pointed out in a previous post, you might want to put your images somewhere else, or adjust your URL You get a path_info part only for the virtual component of your URL (ie. there's no filesystem component beyond /tt ), but your URL for images/hello.gif is relative to /tt, which means your handler for Location /tt has got to fix things up. ...or.. If you make the URL hello.gif to resolve to something outside /tt, then Apache should serve it up as a regular file, which I suspect is what you want. HTH Lyle Quoting Tim Noll ([EMAIL PROTECTED]): Whoops, I hacked up my example a little to make it easier it to read, and I accidentally removed the line: $file =~ s{^/}{}; But, it was in the original. Really. :-) -Tim - Original Message - From: Lyle Brooks [EMAIL PROTECTED] To: Tim Noll [EMAIL PROTECTED] Cc: [EMAIL PROTECTED] Sent: Tuesday, February 05, 2002 4:42 PM Subject: Re: image corruption When I try this example, I find that this line my $file = $r-path_info; will set $file to /index.html when I request the URL /tt/index.html which leads to an error message that says, reason: file error - /index.html: absolute paths are not allowed (set ABSOLUTE option) You may want to clip off the leading slash or set the Template Toolkit option ABSOLUTE, depending on which suits your needs. Quoting Tim Noll ([EMAIL PROTECTED]): I'm attempting to use mod_perl and Template Toolkit to serve up templates. However, I'm having a problem with the images in those templates: They're passing through the content handler, and thus getting corrupted. My first thought was to return DECLINED from the content handler if the request is not for text/html content; however, since I'm using a Location directive, the content_type is always empty since there's no direct mapping to an actual image file. I could use an Alias to map the URI to the file, but then I wouldn't have the path_info that I'm using to call the template. Since my test code, using path_info, is based on an example from the Template Toolkit docs, I feel like I'm probably overlooking something basic. So, I'd appreciate it if someone could show me the error of my ways. :-) Here are the relevant chunks of config and code: from httpd.conf --- ... Location /tt SetHandler perl-script PerlHandler Apache::Test::Mod PerlSetVar WEBROOT /usr/local/apache/tt/html /Location ... Apache::Test::Mod - ... sub handler { my $r = shift; # this doesn't work #return DECLINED unless $r-content_type eq 'text/html'; my $WEBROOT = $r-dir_config('WEBROOT') or return fail( $r, SERVER_ERROR, 'WEBROOT' not specified ); my $file = $r-path_info; my $vars = { content = $r-content_type, }; $r-content_type('text/html'); $r-no_cache(1); my $template = Template-new( { INCLUDE_PATH = $WEBROOT:$WEBROOT/include, OUTPUT = $r, } ); $template-process( $file, $vars, $r) or return fail( $r, SERVER_ERROR, $template-error ); $r-send_http_header(); $r-print( $output ); return OK; } ... index.html (test template) -- html head titletest/title /head body pcontent_type: [% content %]/p pimage: img src=images/hello.gif/p /body /html Thanks. -Tim
image corruption
I'm attempting to use mod_perl and Template Toolkit to serve up templates. However, I'm having a problem with the images in those templates: They're passing through the content handler, and thus getting corrupted. My first thought was to return DECLINED from the content handler if the request is not for text/html content; however, since I'm using a Location directive, the content_type is always empty since there's no direct mapping to an actual image file. I could use an Alias to map the URI to the file, but then I wouldn't have the path_info that I'm using to call the template. Since my test code, using path_info, is based on an example from the Template Toolkit docs, I feel like I'm probably overlooking something basic. So, I'd appreciate it if someone could show me the error of my ways. :-) Here are the relevant chunks of config and code: from httpd.conf --- ... Location /tt SetHandler perl-script PerlHandler Apache::Test::Mod PerlSetVar WEBROOT /usr/local/apache/tt/html /Location ... Apache::Test::Mod - ... sub handler { my $r = shift; # this doesn't work #return DECLINED unless $r-content_type eq 'text/html'; my $WEBROOT = $r-dir_config('WEBROOT') or return fail( $r, SERVER_ERROR, 'WEBROOT' not specified ); my $file = $r-path_info; my $vars = { content = $r-content_type, }; $r-content_type('text/html'); $r-no_cache(1); my $template = Template-new( { INCLUDE_PATH = $WEBROOT:$WEBROOT/include, OUTPUT = $r, } ); $template-process( $file, $vars, $r) or return fail( $r, SERVER_ERROR, $template-error ); $r-send_http_header(); $r-print( $output ); return OK; } ... index.html (test template) -- html head titletest/title /head body pcontent_type: [% content %]/p pimage: img src=images/hello.gif/p /body /html Thanks. -Tim
Re: image corruption
Whoops, I hacked up my example a little to make it easier it to read, and I accidentally removed the line: $file =~ s{^/}{}; But, it was in the original. Really. :-) -Tim - Original Message - From: Lyle Brooks [EMAIL PROTECTED] To: Tim Noll [EMAIL PROTECTED] Cc: [EMAIL PROTECTED] Sent: Tuesday, February 05, 2002 4:42 PM Subject: Re: image corruption When I try this example, I find that this line my $file = $r-path_info; will set $file to /index.html when I request the URL /tt/index.html which leads to an error message that says, reason: file error - /index.html: absolute paths are not allowed (set ABSOLUTE option) You may want to clip off the leading slash or set the Template Toolkit option ABSOLUTE, depending on which suits your needs. Quoting Tim Noll ([EMAIL PROTECTED]): I'm attempting to use mod_perl and Template Toolkit to serve up templates. However, I'm having a problem with the images in those templates: They're passing through the content handler, and thus getting corrupted. My first thought was to return DECLINED from the content handler if the request is not for text/html content; however, since I'm using a Location directive, the content_type is always empty since there's no direct mapping to an actual image file. I could use an Alias to map the URI to the file, but then I wouldn't have the path_info that I'm using to call the template. Since my test code, using path_info, is based on an example from the Template Toolkit docs, I feel like I'm probably overlooking something basic. So, I'd appreciate it if someone could show me the error of my ways. :-) Here are the relevant chunks of config and code: from httpd.conf --- ... Location /tt SetHandler perl-script PerlHandler Apache::Test::Mod PerlSetVar WEBROOT /usr/local/apache/tt/html /Location ... Apache::Test::Mod - ... sub handler { my $r = shift; # this doesn't work #return DECLINED unless $r-content_type eq 'text/html'; my $WEBROOT = $r-dir_config('WEBROOT') or return fail( $r, SERVER_ERROR, 'WEBROOT' not specified ); my $file = $r-path_info; my $vars = { content = $r-content_type, }; $r-content_type('text/html'); $r-no_cache(1); my $template = Template-new( { INCLUDE_PATH = $WEBROOT:$WEBROOT/include, OUTPUT = $r, } ); $template-process( $file, $vars, $r) or return fail( $r, SERVER_ERROR, $template-error ); $r-send_http_header(); $r-print( $output ); return OK; } ... index.html (test template) -- html head titletest/title /head body pcontent_type: [% content %]/p pimage: img src=images/hello.gif/p /body /html Thanks. -Tim
Re: problems with DirectoryIndex under mod_perl + Template Toolkit
Unfortunately, I could not get Apache::ShowRequest to compile, despite tinkering with it quite a bit. But, per your suggestion, I wrote a Fixup handler to solve this problem. However, in my web searches, I came across post after post that seem to describe the same problem or something similar. In no case have I seen a straightforward solution. Is there some reason why this isn't easier to handle if indeed it's such a common problem? -Tim - Original Message - From: Stas Bekman [EMAIL PROTECTED] To: Tim Noll [EMAIL PROTECTED] Cc: [EMAIL PROTECTED]; [EMAIL PROTECTED] Sent: Wednesday, January 30, 2002 6:07 AM Subject: Re: problems with DirectoryIndex under mod_perl + Template Toolkit Tim Noll wrote: Tim, this question is not-related to TT, but a pure configuration issue. So in further postings about this issue please don't CC the tt list. (CC'ing only once now). I'm using mod_perl + Template Toolkit, and I'm having trouble getting Apache to pass the DirectoryIndex to my handler. The handler is supposed to take the path_info and pull a template of the same name from a subdirectory called 'html'. This works fine for file names which do exist in the subdirectory. And, if they don't exist, an error is correctly generated. However, if the path is empty or '/', I expect Apache to include the DirectoryIndex (index.html) in path_info or somewhere else that I can get to it. Unfortunately, Apache is passing empty paths and '/' straight through to the handler, causing a file not found error. Maybe I'm just not looking in the right place, but I've spent a lot of time Googling and looking at the mod_perl guide, and I can't seem to find an exact answer to my problem. This would seem to be a common issue. Can anyone offer a solution? That's the job of mod_dir to do that translation from / to /index.html. Does it run? For example you can use Apache::ShowRequest to look what handlers are running. In your case the best thing is to write a Fixup handler and do what mod_dir does in Perl (should be two lines of code). Here is a section from our book with an example of using Apache::ShowRequest: =head2 Investigating the Request Phases Imagine a situation where you have a complex server setup in which many different Perl and non-Perl handlers participate in the request processing, and one or more of these handlers misbehave. A simple example would be where one of the handlers alters the request record, which breaks the functionality of the other handler. Or some handler invoked first in for any given phase of the process and returns COK status, when it's not expected to do so, thus preventing other handlers from doing their job. You can't just add debug statements to trace the offender--there are too many handlers involved. The simplest solution is to get a trace of all registered handlers for each phase, stating whether they were invoked or not and what was the return status. Once such a trace is available, it's much easier to look only at the players who did something, thus narrowing the search path for a potential misbehaving module. The CApache::ShowRequest module shows the phases the request goes through, displaying the module participation in each phase and respond codes. The content response phase is not run, but possible modules are listed as defined. To configure it, just add this snippet to Ihttpd.conf: Location /showrequest SetHandler perl-script PerlHandler +Apache::ShowRequest /Location Now if you want to see what happens when you access some URI, just add it after I/showrequest. CApache::ShowRequest uses the CPATH_INFO to get to the URI that should be executed. So to run I/index.html with CApache::ShowRequest, issue a request to I/showrequest/index.html. For I/perl/test.pl, issue a request to I/showrequest/perl/test.pl. This module produces rather lengthy output, so we will show only one section from the report generated while requesting: I/showrequest/index.html: Running request for /index.html Request phase: post_read_request [snip] Request phase: translate_handler mod_perl DECLINED mod_setenvif undef mod_auth undef mod_access ..undef mod_alias ...DECLINED mod_userdir .DECLINED mod_actions .undef mod_imap undef mod_asis undef mod_cgi .undef mod_dir .undef mod_autoindex ...undef mod_include .undef mod_info undef mod_status ..undef mod_negotiation .undef mod_mime undef mod_log_config ..undef mod_env .undef http_core
problems with DirectoryIndex under mod_perl + Template Toolkit
I'm using mod_perl + Template Toolkit, and I'm having trouble getting Apache to pass the DirectoryIndex to my handler. The handler is supposed to take the path_info and pull a template of the same name from a subdirectory called 'html'. This works fine for file names which do exist in the subdirectory. And, if they don't exist, an error is correctly generated. However, if the path is empty or '/', I expect Apache to include the DirectoryIndex (index.html) in path_info or somewhere else that I can get to it. Unfortunately, Apache is passing empty paths and '/' straight through to the handler, causing a file not found error. Maybe I'm just not looking in the right place, but I've spent a lot of time Googling and looking at the mod_perl guide, and I can't seem to find an exact answer to my problem. This would seem to be a common issue. Can anyone offer a solution? Admittedly, I'm new to Apache, mod_perl and Template Toolkit, and I'm getting my feet wet trying to learn all three using my Windows 2000 workstation as a test bed, although the eventual target server will be running Linux. Below is some sample code (mostly copied/modified from various online sources) that I boiled down in an attempt to solve the problem, but to no avail. Thanks in advance. -Tim httpd.conf -- # default win32 config up to here ... # mod_perl config Include conf/perl.conf -- perl.conf - LoadModule perl_module modules/mod_perl.so AddModule mod_perl.c PerlRequire conf/startup.pl PerlWarn On PerlTaintCheck On PerlFreshRestart On PerlSetVar websrc /usr/local/apache/tt Location /tt SetHandler perl-script PerlHandler Test::Mod /Location -- startup.pl -- #!/usr/bin/perl -w use strict; BEGIN { # modify include path use Apache (); use lib Apache-server_root_relative('lib/perl'); } # are we under mod_perl? $ENV{MOD_PERL} or die(not running under mod_perl); # detailed warnings use Carp (); $SIG{__WARN__} = \Carp::cluck; # load common modules use Apache::Constants (); use Template (); # load custom modules use Test::Mod (); 1; -- Test/Mod.pm --- #!/usr/bin/perl -wT package Test::Mod; use strict; use Apache::Constants qw( :common ); use Template qw( :template ); our $VERSION = 0.01; sub handler { my $r = shift; my $websrc = $r-dir_config('websrc') or return fail( $r, SERVER_ERROR, 'websrc' not specified ); my $template = Template-new({ INCLUDE_PATH = $websrc:$websrc/html:$websrc/html/include, OUTPUT = $r, }); # use the path_info to determine which template file to process my $file = $r-path_info(); $file =~ s[^/][]; my $vars = { uri = $r-uri(), file = $r-filename(), path = $r-path_info(), tt = $file, }; $r-content_type('text/html'); $r-no_cache(1); $r-send_http_header(); $template-process($file, $vars) or return fail( $r, SERVER_ERROR, $template-error() ); return OK; } sub fail { my ($r, $status, $message) = @_; $r-log_reason( $message, $r-filename() ); return $status; } -- index.html -- [% PROCESS header.html title = 'template test' %] puri: [% uri %]/p pfile: [% file %]/p ppath: [% path %]/p ptemplate: [% tt %]/p [% PROCESS footer.html %]