You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by David Christensen <dp...@holgerdanske.com> on 2005/07/01 03:23:13 UTC

Eagle book RandPicture.pm, $r->internal_redirect, and IE 6.0 showing same image every time

modperl:

I'm a mod_perl newbie working my way through the Eagle book
(http://www.modperl.com/), and have implemented RandPicture.pm per pp. 126-127.
Everything works as expected using $r->header_out(Location => $lucky_one) and
REDIRECT, and also using the $subr->run optimization per p. 128.


When I implement the $r->internal_redirect optimization per p. 129 (see source
code, below), IE 6.0 displays the same image every time, even though
RandPicture.pm seems to be selecting different images (see debugging information
in error log, below).


I have tried clearing the browser's cache and turning caching off, but the issue
remains.


Any suggestions?


TIA,

David
--

host: Debian 3.1r0

root@p166v:~# apt-cache showpkg apache-perl
Package: apache-perl
Versions:
1.3.33-6(/var/lib/apt/lists/ftp.us.debian.org_debian_dists_stable_main_binary-i3
86_Packages)(/var/lib/dpkg/status)

Reverse Depends:
  zoph,apache-perl
  webmin-virtual-server,apache-perl
  webmin-apache,apache-perl
  slash,apache-perl
  scoop,apache-perl
  request-tracker3.4,apache-perl
  request-tracker3,apache-perl
  piwi,apache-perl
  phpmyadmin,apache-perl
  phpix,apache-perl
  otrs,apache-perl
  opendb,apache-perl
  myphpmoney,apache-perl 1.3.29.0.1-1
  mantis,apache-perl 1.3.29.0.2-2
  lxr-cvs,apache-perl
  libmasonx-request-withapachesession-perl,apache-perl
  libhtml-mason-perl-examples,apache-perl
  libhtml-embperl-perl,apache-perl 1.3.14
  libapache-reload-perl,apache-perl
  libapache-mod-ssl,apache-perl
  libapache-mod-jk,apache-perl
  libapache-mod-encoding,apache-perl
  libapache-mod-auth-radius,apache-perl
  libapache-db-perl,apache-perl
  libapache-authensmb,apache-perl
  irm,apache-perl
  ilohamail,apache-perl
  gforge-web-apache,apache-perl 1.3.29.0.1-1
  gforge-lists-mailman,apache-perl 1.3.9
  gforge-cvs,apache-perl 1.3.9
  gallery,apache-perl
  fibusql,apache-perl 1.3.29.0.1-1
  eskuel,apache-perl
  egroupware-core,apache-perl 1.3.29.0.1
  drupal,apache-perl
  diatheke,apache-perl
  cacti,apache-perl
  bugzilla,apache-perl
  backuppc,apache-perl
  axyl,apache-perl 1.3
  apache-doc,apache-perl
  apache-dev,apache-perl
  apache-dbg,apache-perl
  apache-common,apache-perl
Dependencies:
1.3.33-6 - libc6 (2 2.3.2.ds1-21) libdb4.2 (0 (null)) libexpat1 (2 1.95.8)
libperl5.8 (2 5.8.4) mime-support (0 (null)) apache-common (2 1.3.33-6)
apache-common (3 1.3.34-0) libapache-mod-perl (2 1.29.0.2-9) libapache-mod-perl
(3 1.30) debconf (0 (null)) dpkg (4 1.9.0) libmagic1 (0 (null)) logrotate (2
3.5.4-1) apache-doc (0 (null)) apache-modules (0 (null)) jserv (1 1.1-3)
Provides:
1.3.33-6 - httpd httpd-cgi
Reverse Provides:



perl.conf:

<Location /random/picture>
    SetHandler	perl-script
    PerlHandler	Apache::RandomPicture
    PerlSetVar	PictureDir	/images
</Location>



RandomPicture.pm:

#######################################################################
# $Id: RandomPicture.pm,v 1.3 2005/06/30 03:52:18 dpchrist Exp $
#
# Redirect to random picture per [1] pp. 123-128.
#
# Copyright 2005 by David Christensen <dp...@holgerdanske.com>
#
# References:
#
# [1]  Lincoln Stein & Doug MacEachern, 1999, "Wring Apache Modules
#      with Perl and C", O'Reilly, ISBN 1-56592-567-X.
#######################################################################
# Apache::NavBar package:
#----------------------------------------------------------------------

package Apache::RandomPicture;

#######################################################################
# uses:
#----------------------------------------------------------------------

use strict;
use warnings;

use Apache::Constants	qw(:common REDIRECT DOCUMENT_FOLLOWS);
use Data::Dumper;
use DirHandle;

$Data::Dumper::Indent = 0;

#######################################################################
# package globals:
#----------------------------------------------------------------------

our $debug = 1;

our $picturedir_directive = 'PictureDir';

#######################################################################
# subroutines:
#----------------------------------------------------------------------

sub handler
{
    $_[0]->log_error(sprintf("%s (%s %s): ",
    	    (caller(0))[3], __FILE__, __LINE__),
	    Data::Dumper->Dump([\@_], [qw(*_)])) if $debug;

    my $r = shift;

    my $retval = DECLINED;	##### pessimistic execution

    my $dir_uri = $r->dir_config($picturedir_directive);
    unless ($dir_uri) {
	$r->log_error(sprintf("%s (%s %s): ",
	    (caller(0))[3], __FILE__, __LINE__),
	    "unable to find Apache configuration directive ",
	    "'$picturedir_directive'");
	goto done;
    }
    $dir_uri .= '/' unless $dir_uri =~ m:/$:;
    $r->log_error(sprintf("%s (%s %s): ",
	(caller(0))[3], __FILE__, __LINE__),
	Data::Dumper->Dump([$dir_uri], [qw(dir_uri)])) if $debug;

    my $subr = $r->lookup_uri($dir_uri);
    my $dir = $subr->filename;
    $r->log_error(sprintf("%s (%s %s): ",
	(caller(0))[3], __FILE__, __LINE__),
	Data::Dumper->Dump([$dir], [qw(dir)])) if $debug;
    my $dh = DirHandle->new($dir);
    unless ($dh) {
	$r->log_error(sprintf("%s (%s %s): ",
	    (caller(0))[3], __FILE__, __LINE__),
	    "unable to read directory '$dir': $!");
	goto done;
    }

    my @files;
    for my $entry ($dh->read) {
	my $rr = $subr->lookup_uri($entry);
	my $type = $rr->content_type;
	next unless $type =~ m:^image/:;
	push @files, $rr->uri;
    }
    $dh->close;
    unless (scalar @files) {
	$r->log_error(sprintf("%s (%s %s): ",
	    (caller(0))[3], __FILE__, __LINE__),
	    "no image files found in directory '$dir'");
	goto done;
    }
    $r->log_error(sprintf("%s (%s %s): ",
	(caller(0))[3], __FILE__, __LINE__),
	Data::Dumper->Dump([\@files], [qw(*files)])) if $debug;

    my $lucky_one = $files[rand scalar @files];
    $r->log_error(sprintf("%s (%s %s): ",
	(caller(0))[3], __FILE__, __LINE__),
	Data::Dumper->Dump([$lucky_one], [qw(lucky_one)])) if $debug;

    my $lucky_uri = $r->lookup_uri($lucky_one);
    unless ($lucky_uri->status == DOCUMENT_FOLLOWS) {
	$r->log_error(sprintf("%s (%s %s): ",
	    (caller(0))[3], __FILE__, __LINE__),
	    "error looking up URI '$lucky_one'");
	goto done;
    }

    $r->content_type($lucky_uri->content_type);
    if ($r->header_only) {
	$r->send_http_header;
    }
    else {
	$r->internal_redirect($lucky_one);
    }
    
    $retval = OK;

  done:
    $r->log_error(sprintf("%s (%s %s): ",
	(caller(0))[3], __FILE__, __LINE__),
	Data::Dumper->Dump([$retval], [qw(retval)])) if $debug;
    return $retval;
}

#######################################################################
# end of code:
#----------------------------------------------------------------------

1;

__END__

#######################################################################



apache-perl error log sample after browsing to
http://192.168.254.3/random/picture, hitting refreshing, going back, and
browsing again (2075_1.jpg was displayed all three times):

root@p166v:~# tail -n 22 /var/log/apache-perl/error.log
[Thu Jun 30 18:10:29 2005] [notice] SIGUSR1 received.  Doing graceful restart
[Thu Jun 30 18:10:33 2005] CGI.pm: Constant subroutine CGI::XHTML_DTD redefined
at /usr/share/perl/5.8/constant.pm line 108.
[Thu Jun 30 18:10:33 2005] [notice] Apache/1.3.33 (Debian GNU/Linux)
mod_perl/1.29 configured -- resuming normal operations
[Thu Jun 30 18:10:33 2005] [notice] Accept mutex: sysvsem (Default: sysvsem)
[Thu Jun 30 18:10:37 2005] [error] Apache::RandomPicture::handler
(/home/dpchrist/eagle-book/lib/perl/Apache/RandomPicture.pm 46): @_ = (bless(
do{\\(my $o = 139092700)}, 'Apache' ));
[Thu Jun 30 18:10:37 2005] [error] Apache::RandomPicture::handler
(/home/dpchrist/eagle-book/lib/perl/Apache/RandomPicture.pm 63): $dir_uri =
'/images/';
[Thu Jun 30 18:10:37 2005] [error] Apache::RandomPicture::handler
(/home/dpchrist/eagle-book/lib/perl/Apache/RandomPicture.pm 69): $dir =
'/home/dpchrist/eagle-book/images';
[Thu Jun 30 18:10:37 2005] [error] Apache::RandomPicture::handler
(/home/dpchrist/eagle-book/lib/perl/Apache/RandomPicture.pm 94): @files =
('/images/2075_1.jpg','/images/2075_2.jpg','/images/2075_3.jpg','/images/2075_4.
jpg');
[Thu Jun 30 18:10:37 2005] [error] Apache::RandomPicture::handler
(/home/dpchrist/eagle-book/lib/perl/Apache/RandomPicture.pm 99): $lucky_one =
'/images/2075_1.jpg';
[Thu Jun 30 18:10:38 2005] [error] Apache::RandomPicture::handler
(/home/dpchrist/eagle-book/lib/perl/Apache/RandomPicture.pm 122): $retval = 0;
[Thu Jun 30 18:10:39 2005] [error] Apache::RandomPicture::handler
(/home/dpchrist/eagle-book/lib/perl/Apache/RandomPicture.pm 46): @_ = (bless(
do{\\(my $o = 139092700)}, 'Apache' ));
[Thu Jun 30 18:10:39 2005] [error] Apache::RandomPicture::handler
(/home/dpchrist/eagle-book/lib/perl/Apache/RandomPicture.pm 63): $dir_uri =
'/images/';
[Thu Jun 30 18:10:39 2005] [error] Apache::RandomPicture::handler
(/home/dpchrist/eagle-book/lib/perl/Apache/RandomPicture.pm 69): $dir =
'/home/dpchrist/eagle-book/images';
[Thu Jun 30 18:10:39 2005] [error] Apache::RandomPicture::handler
(/home/dpchrist/eagle-book/lib/perl/Apache/RandomPicture.pm 94): @files =
('/images/2075_1.jpg','/images/2075_2.jpg','/images/2075_3.jpg','/images/2075_4.
jpg');
[Thu Jun 30 18:10:39 2005] [error] Apache::RandomPicture::handler
(/home/dpchrist/eagle-book/lib/perl/Apache/RandomPicture.pm 99): $lucky_one =
'/images/2075_3.jpg';
[Thu Jun 30 18:10:39 2005] [error] Apache::RandomPicture::handler
(/home/dpchrist/eagle-book/lib/perl/Apache/RandomPicture.pm 122): $retval = 0;
[Thu Jun 30 18:10:42 2005] [error] Apache::RandomPicture::handler
(/home/dpchrist/eagle-book/lib/perl/Apache/RandomPicture.pm 46): @_ = (bless(
do{\\(my $o = 139092700)}, 'Apache' ));
[Thu Jun 30 18:10:42 2005] [error] Apache::RandomPicture::handler
(/home/dpchrist/eagle-book/lib/perl/Apache/RandomPicture.pm 63): $dir_uri =
'/images/';
[Thu Jun 30 18:10:42 2005] [error] Apache::RandomPicture::handler
(/home/dpchrist/eagle-book/lib/perl/Apache/RandomPicture.pm 69): $dir =
'/home/dpchrist/eagle-book/images';
[Thu Jun 30 18:10:42 2005] [error] Apache::RandomPicture::handler
(/home/dpchrist/eagle-book/lib/perl/Apache/RandomPicture.pm 94): @files =
('/images/2075_1.jpg','/images/2075_2.jpg','/images/2075_3.jpg','/images/2075_4.
jpg');
[Thu Jun 30 18:10:42 2005] [error] Apache::RandomPicture::handler
(/home/dpchrist/eagle-book/lib/perl/Apache/RandomPicture.pm 99): $lucky_one =
'/images/2075_2.jpg';
[Thu Jun 30 18:10:43 2005] [error] Apache::RandomPicture::handler
(/home/dpchrist/eagle-book/lib/perl/Apache/RandomPicture.pm 122): $retval = 0;



Re: Eagle book RandPicture.pm, $r->internal_redirect, and IE 6.0 showing same image every time

Posted by Slava Bizyayev <sb...@outlook.net>.
On Fri, 2005-07-01 at 09:10, Geoffrey Young wrote:
> Slava Bizyayev wrote:
> > On Thu, 2005-06-30 at 22:52, David Christensen wrote:
> > 
> >>1.  Make a mod_perl call that tells the browser not to cache the
> >>    upcoming document.  (Does such a call exist?)
> > 
> > 
> > Take a look at Expires HTTP header. See rfc2616 for additional details.
> 
>   $r->no_cache(1) is probably simpler :)

agree (assuming that the implementation is sufficient and universal)..

> > 
> > 
> >>2.  Make a mod_perl call that tells the browser that the upcoming
> >>    document is newer than the last one requested (I might be able to
> >>    implement this idea using time(), update_mtime(), and
> >>    set_last_modified(), but it seems like a crude hack).
> > 
> > 
> > Sounds like an unnecessary hack. 
> 
> say the current image in msie has a newer mtime on disk than the image
> you're about to redirect to.

But initially there is no locally cached content. All you need to do at
this point -- is to make sure that there were no caching proxies on your
way. So, Vary * makes it simple. ;-)

Thanks,
Slava



RE: Eagle book RandPicture.pm, $r->internal_redirect, and IE 6.0 showing same image every time

Posted by David Christensen <dp...@holgerdanske.com>.
modperl:

I found confirmation regarding the issue of headers getting lost on internal
redirection on p. 172 of the Eagle book:

    "Another important detail about error handling is that Apache
    ignores the fields that you set with header_out() when your module
    generates an error status or invokes an internal redirect."


Reading further:

    "For these cases, call the request object's err_header_out()
    method.  It has identical syntax to header_out(), but the fields
    that you set with it are sent to the browser only when an error has
    occurred.  Unlike ordinary headers, the fields set with
    err_header_out() persist across internal redirections..."


RTM perldoc Apache under $r->err_headers_out:

    "The difference between headers_out and err_headers_out is that the
    latter are printed even on error, and persist across internal redi-
    rects (so the headers printed for ErrorDocument handlers will have
    them).


So, I tried using err_headers_out to set "Pragma: no-cache" and "Cache-control:
no-cache" headers.  wget sees them, but IE still displays the same picture.  :-(


STFW:

    http://support.microsoft.com/kb/q222064/


Interesting, but an unworkable "RESOLUTION".  Looking some more:

    http://support.microsoft.com/kb/q234067/


So, I added an "Expires: -1" header.  Strange.  It seemed to work for a few
clicks, and then got stuck.  I guess this first few were the different Apache
children sending different pictures, but once the newest picture was sent, the
browser got stuck on its cache (?).  Dig some more:

    http://psacake.com/web/s.asp


Implement "Expires: 0" and Expiresabsolute as time() - 1.  Nope.  Not even a
teaser.


Try setting Expires to time() -1.  Nope.


Try setting Expires to time() - 24*3600.  Nope.


Dig some more:

    http://www.phpbuilder.com/tips/item.php?id=123


Looks like it's worth giving a try.  But, how do I set the same header three
times?  Hmmm...  Looks like err_header_out() doesn't accept an array ref, and
calling it multiple times just steps on previous values.  After beating my head
against that for a while, it turns out that "Cache-control: max-age=0" seems to
be enough.  It also looks like Expires and "Pragma: no-cache" are unnecessary.


So, to prevent caching in IE 6.0 SP2 when using Apache 1.3.33
internal_redirect(), call err_header_out() and set the "Last-Modified" header to
the current time and the "Cache-control" header to "max-age=0".


HTH,

David



#######################################################################
# $Id: RandomPicture.pm,v 1.7 2005/07/17 03:03:17 dpchrist Exp $
#
# Redirect to random picture per [1] pp. 123-128 using internal
# redirection and err_header_out().
#
# Copyright 2005 by David Christensen <dp...@holgerdanske.com>
#
# References:
#
# [1]  Lincoln Stein & Doug MacEachern, 1999, "Writing Apache Modules
#      with Perl and C", O'Reilly, ISBN 1-56592-567-X.
#######################################################################
# Apache::NavBar package:
#----------------------------------------------------------------------

package Apache::RandomPicture;

#######################################################################
# uses:
#----------------------------------------------------------------------

use strict;
use warnings;

use Apache::Constants	qw(:common REDIRECT DOCUMENT_FOLLOWS);
use Data::Dumper;
use DirHandle;

$Data::Dumper::Indent = 0;

#######################################################################
# package globals:
#----------------------------------------------------------------------

our $debug = 1;

our $picturedir_directive = 'PictureDir';

#######################################################################
# subroutines:
#----------------------------------------------------------------------

sub handler
{
    $_[0]->log_error(sprintf("%s (%s %s): ",
    	    (caller(0))[3], __FILE__, __LINE__),
	    Data::Dumper->Dump([\@_], [qw(*_)])) if $debug;

    my $r = shift;

    my $retval = DECLINED;	##### pessimistic execution

    my $dir_uri = $r->dir_config($picturedir_directive);
    unless ($dir_uri) {
	$r->log_error(sprintf("%s (%s %s): ",
	    (caller(0))[3], __FILE__, __LINE__),
	    "unable to find Apache configuration directive ",
	    "'$picturedir_directive'");
	goto done;
    }
    $dir_uri .= '/' unless $dir_uri =~ m:/$:;
    $r->log_error(sprintf("%s (%s %s): ",
	(caller(0))[3], __FILE__, __LINE__),
	Data::Dumper->Dump([$dir_uri], [qw(dir_uri)])) if $debug;

    my $subr = $r->lookup_uri($dir_uri);
    my $dir = $subr->filename;
    $r->log_error(sprintf("%s (%s %s): ",
	(caller(0))[3], __FILE__, __LINE__),
	Data::Dumper->Dump([$dir], [qw(dir)])) if $debug;
    my $dh = DirHandle->new($dir);
    unless ($dh) {
	$r->log_error(sprintf("%s (%s %s): ",
	    (caller(0))[3], __FILE__, __LINE__),
	    "unable to read directory '$dir': $!");
	goto done;
    }

    my @files;
    for my $entry ($dh->read) {
	my $rr = $subr->lookup_uri($entry);
	my $type = $rr->content_type;
	next unless $type =~ m:^image/:;
	push @files, $rr->uri;
    }
    $dh->close;
    unless (scalar @files) {
	$r->log_error(sprintf("%s (%s %s): ",
	    (caller(0))[3], __FILE__, __LINE__),
	    "no image files found in directory '$dir'");
	goto done;
    }
    $r->log_error(sprintf("%s (%s %s): ",
	(caller(0))[3], __FILE__, __LINE__),
	Data::Dumper->Dump([\@files], [qw(*files)])) if $debug;

    my $lucky_one = $files[rand scalar @files];
    $r->log_error(sprintf("%s (%s %s): ",
	(caller(0))[3], __FILE__, __LINE__),
	Data::Dumper->Dump([$lucky_one], [qw(lucky_one)])) if $debug;

    my $lucky_uri = $r->lookup_uri($lucky_one);
    $r->log_error(sprintf("%s (%s %s): ",
	(caller(0))[3], __FILE__, __LINE__),
	Data::Dumper->Dump([$lucky_uri], [qw(lucky_uri)])) if $debug;
    unless ($lucky_uri->status == DOCUMENT_FOLLOWS) {
	$r->log_error(sprintf("%s (%s %s): ",
	    (caller(0))[3], __FILE__, __LINE__),
	    "error looking up URI '$lucky_one'");
	goto done;
    }

    $r->content_type($lucky_uri->content_type);
    if ($r->header_only) {
	$r->send_http_header;
    }
    else {
	my %err_headers_out = $r->err_headers_out;
	$r->log_error(sprintf("%s (%s %s): ",
	    (caller(0))[3], __FILE__, __LINE__),
	    Data::Dumper->Dump([\%err_headers_out],
			      [qw(err_headers_out)])) if $debug;

##### After much pain and suffering, these are the headers needed for
##### IE 6.0 SP2 to display the picture Apache was sending, rather than
##### using it's cache.  The clue came from here:
#####     http://www.phpbuilder.com/tips/item.php?id=123

##### This one doesn't seem to be necessary.
#	$r->err_header_out("Expires" => 0);

##### Subrequest will send a "Last-Modified" header per the document
##### date/time stamp.  Commenting this out causes IE to cache.  I
##### guess IE uses the most recent of the two headers (?), so we
##### need this:
	$r->err_header_out("Last-Modified" => time());

##### err_header_out() doesn't seem to accept multiple values for the
##### same header (I tried an array ref; no luck).  Subsequent calls
##### step on the value (scalar) set by previous calls.  The first
##### header alone doesn't work.  The second and third headers alone
##### seem to stop caching.  Use the third one.
#	$r->err_header_out("Cache-control"=>"no-cache");
#	$r->err_header_out("Cache-control"=>"post-check=0,pre-check=0");
        $r->err_header_out("Cache-control"=>"max-age=0");

##### This one doesn't seem to be necessary.
#	$r->err_header_out("Pragma" => "no-cache");
	
	%err_headers_out = $r->err_headers_out;
	$r->log_error(sprintf("%s (%s %s): ",
	    (caller(0))[3], __FILE__, __LINE__),
	    Data::Dumper->Dump([\%err_headers_out],
			      [qw(err_headers_out)])) if $debug;
	$r->internal_redirect($lucky_one);
    }
    
    $retval = OK;

  done:
    $r->log_error(sprintf("%s (%s %s): ",
	(caller(0))[3], __FILE__, __LINE__),
	Data::Dumper->Dump([$retval], [qw(retval)])) if $debug;
    return $retval;
}

#######################################################################
# end of code:
#----------------------------------------------------------------------

1;

__END__

#######################################################################


RE: Eagle book RandPicture.pm, $r->internal_redirect, and IE 6.0 showing same image every time

Posted by David Christensen <dp...@holgerdanske.com>.
Geoffrey Young wrote:
> ... here's the code from http_request.c in 1.3:
>    request_rec *new;
>    ...
>    new->headers_in      = r->headers_in;
>    new->headers_out     = ap_make_table(r->pool, 12);
> ... this is an apache thing, not a mod_perl thing,

Okay.


>  my $sub = $r->lookup_uri($lucky);
>  $sub->no_cache(1);
>  $sub->run;

It looks like $r->run() is the best answer. (BTW it works without the call to
no_cache(1).)


Thanks!  :-)

David


Re: Eagle book RandPicture.pm, $r->internal_redirect, and IE 6.0 showing same image every time

Posted by Geoffrey Young <ge...@modperlcookbook.org>.
> I added some debug logging to see headers_out() before and after calling
> no_cache(1).  no_cache(1) appears to be setting the specified headers and
> internal_redirect() appears to be ignoring them.

alright, I think I see what's going on here.  I'll explain technically and
then try to explain the rationale I think is behind it.

the reason $r->no_cache(1) isn't affecting your code is that an
internal_redirect() is purposefully ignoring the headers_out table when it
issues the redirect.  to paraphrase the code, when you call
$r->internal_redirect apache creates a _new_ request and sends that request
through the standard request cycle, starting with uri translation.  when the
new request is created it copies various things from the current request,
one of which is _not_ the headers_out table.  here's the code from
http_request.c in 1.3:

    request_rec *new;
    ...
    new->headers_in      = r->headers_in;
    new->headers_out     = ap_make_table(r->pool, 12);

so, when you call $r->internal_redirect() you get the properties of the
incoming request, but inherit none of the properties of current response.

please note this is an apache thing, not a mod_perl thing, so it's nothing
that mod_perl is doing "wrong."  as with almost all that mod_perl does, the
API of internal_redirect() is an apache C one that mod_perl merely passes on
to you in perl.

ok, now for the rationale.  I can only suspect that the reason for this
behavior is that the point of internal_redirect() is to act just like a full
external redirect (ie returning REDIRECT with a Location header) except
you're not letting the browser know about it.  in other words,
internal_redirect() is a transparent replacement of the current content with
content from a different URI, cache headers and all.

in truth, I think the behavior you're observing is the desirable one for the
vast majority of cases of using an internal redirect.  for example, sending
the ETag header from the current request when calling internal_redirect() to
another URI would probably break the rules surrounding ETag, which is
supposed to be unique for each resource.

but of course, none of this helps your code.  hopefully it at least helps
your understanding :)

if you're just playing around I guess the workaround is to use a subrequest
instead of internal_redirect().  for example

  my $sub = $r->lookup_uri($lucky);
  $sub->no_cache(1);
  $sub->run;

if you really want to use internal_redirect() I have a rather complex
solution that _might_ work.  take this module:
  http://www.modperlcookbook.org/code/ch03/Cookbook-SimpleRequest-0.01.tar.gz

crack it open and s/assbackwards/no_local_copy/.  then from your code you
would call $r->no_local_copy(1) instead of $r->no_cache(1).  it's not
guaranteed to work but it probably will :)  of course, in mod_perl 2.0 you
get access to no_local_copy() without the acrobatics.

HTH

--Geoff

RE: Eagle book RandPicture.pm, $r->internal_redirect, and IE 6.0 showing same image every time

Posted by David Christensen <dp...@holgerdanske.com>.
Michael Peters wrote:

> no_cache() should work (or at least it has for me in the past when IE 
> has given me similar headaches).
> That's odd. no_cache should not be sending the 'Expires' header.
> Instead it uses the more forceful 'Pragma: no-cache' and
> 'Cache-control: no-cache'. These are not showing up in your headers.
> The only thing I can think of is that no_cache(1) is not being
> executed?

I added some debug logging to see headers_out() before and after calling
no_cache(1).  no_cache(1) appears to be setting the specified headers and
internal_redirect() appears to be ignoring them.


Any suggestions?


TIA,

David
--



#######################################################################
# $Id: RandomPicture.pm,v 1.6 2005/07/06 00:56:53 dpchrist Exp $
#
# Redirect to random picture per [1] pp. 123-128.
#
# Copyright 2005 by David Christensen <dp...@holgerdanske.com>
#
# References:
#
# [1]  Lincoln Stein & Doug MacEachern, 1999, "Wring Apache Modules
#      with Perl and C", O'Reilly, ISBN 1-56592-567-X.
#######################################################################
# Apache::NavBar package:
#----------------------------------------------------------------------

package Apache::RandomPicture;

#######################################################################
# uses:
#----------------------------------------------------------------------

use strict;
use warnings;

use Apache::Constants	qw(:common REDIRECT DOCUMENT_FOLLOWS);
use Data::Dumper;
use DirHandle;

$Data::Dumper::Indent = 0;

#######################################################################
# package globals:
#----------------------------------------------------------------------

our $debug = 1;

our $picturedir_directive = 'PictureDir';

#######################################################################
# subroutines:
#----------------------------------------------------------------------

sub handler
{
    $_[0]->log_error(sprintf("%s (%s %s): ",
    	    (caller(0))[3], __FILE__, __LINE__),
	    Data::Dumper->Dump([\@_], [qw(*_)])) if $debug;

    my $r = shift;

    my $retval = DECLINED;	##### pessimistic execution

    my $dir_uri = $r->dir_config($picturedir_directive);
    unless ($dir_uri) {
	$r->log_error(sprintf("%s (%s %s): ",
	    (caller(0))[3], __FILE__, __LINE__),
	    "unable to find Apache configuration directive ",
	    "'$picturedir_directive'");
	goto done;
    }
    $dir_uri .= '/' unless $dir_uri =~ m:/$:;
    $r->log_error(sprintf("%s (%s %s): ",
	(caller(0))[3], __FILE__, __LINE__),
	Data::Dumper->Dump([$dir_uri], [qw(dir_uri)])) if $debug;

    my $subr = $r->lookup_uri($dir_uri);
    my $dir = $subr->filename;
    $r->log_error(sprintf("%s (%s %s): ",
	(caller(0))[3], __FILE__, __LINE__),
	Data::Dumper->Dump([$dir], [qw(dir)])) if $debug;
    my $dh = DirHandle->new($dir);
    unless ($dh) {
	$r->log_error(sprintf("%s (%s %s): ",
	    (caller(0))[3], __FILE__, __LINE__),
	    "unable to read directory '$dir': $!");
	goto done;
    }

    my @files;
    for my $entry ($dh->read) {
	my $rr = $subr->lookup_uri($entry);
	my $type = $rr->content_type;
	next unless $type =~ m:^image/:;
	push @files, $rr->uri;
    }
    $dh->close;
    unless (scalar @files) {
	$r->log_error(sprintf("%s (%s %s): ",
	    (caller(0))[3], __FILE__, __LINE__),
	    "no image files found in directory '$dir'");
	goto done;
    }
    $r->log_error(sprintf("%s (%s %s): ",
	(caller(0))[3], __FILE__, __LINE__),
	Data::Dumper->Dump([\@files], [qw(*files)])) if $debug;

    my $lucky_one = $files[rand scalar @files];
    $r->log_error(sprintf("%s (%s %s): ",
	(caller(0))[3], __FILE__, __LINE__),
	Data::Dumper->Dump([$lucky_one], [qw(lucky_one)])) if $debug;

    my $lucky_uri = $r->lookup_uri($lucky_one);
    unless ($lucky_uri->status == DOCUMENT_FOLLOWS) {
	$r->log_error(sprintf("%s (%s %s): ",
	    (caller(0))[3], __FILE__, __LINE__),
	    "error looking up URI '$lucky_one'");
	goto done;
    }

    $r->content_type($lucky_uri->content_type);
    if ($r->header_only) {
	$r->send_http_header;
    }
    else {
	my %headers_out = %{$r->headers_out};
	$r->log_error(sprintf("%s (%s %s): ",
	    (caller(0))[3], __FILE__, __LINE__),
	    "calling no_cache(1)...",
	    Data::Dumper->Dump([\%headers_out], [qw(*headers_out)]));
	my @no_cache = $r->no_cache(1);
	%headers_out = %{$r->headers_out};
	$r->log_error(sprintf("%s (%s %s): ",
	    (caller(0))[3], __FILE__, __LINE__),
	    "no_cache(1) returned ",
	    Data::Dumper->Dump([\@no_cache], [qw(*no_cache)]),
	    Data::Dumper->Dump([\%headers_out], [qw(*headers_out)]));

	$r->log_error(sprintf("%s (%s %s): ",
	    (caller(0))[3], __FILE__, __LINE__),
	    "redirecting to '$lucky_one'");
	$r->internal_redirect($lucky_one);
    }
    
    $retval = OK;

  done:
    $r->log_error(sprintf("%s (%s %s): ",
	(caller(0))[3], __FILE__, __LINE__),
	Data::Dumper->Dump([$retval], [qw(retval)])) if $debug;
    return $retval;
}

#######################################################################
# end of code:
#----------------------------------------------------------------------

1;

__END__

#######################################################################



dpchrist@p42800e:~$ wget -s -nv http://192.168.254.3/random/picture
18:01:48 URL:http://192.168.254.3/random/picture [32752/32752] -> "pictu
re.4" [1] 



dpchrist@p42800e:~$ head -n 12 picture.4
HTTP/1.1 200 OK
Date: Wed, 06 Jul 2005 01:01:10 GMT
Server: Apache/1.3.33 (Debian GNU/Linux) mod_perl/1.29
Last-Modified: Wed, 04 Jun 2003 06:53:10 GMT
ETag: "1064a-7ff0-3edd9756;42c4b3fd"
Accept-Ranges: bytes
Content-Length: 32752
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Content-Type: image/jpeg
Expires: Wed, 06 Jul 2005 01:01:10 GMT



root@p166v:~# tail -n 8 /var/log/apache-perl/error.log  | grep no_cache
[Tue Jul  5 18:01:10 2005] [error] Apache::RandomPicture::handler (/home
/dpchrist/eagle-book/lib/perl/Apache/RandomPicture.pm 117): calling no_c
ache(1)...%headers_out = ();
[Tue Jul  5 18:01:10 2005] [error] Apache::RandomPicture::handler (/home
/dpchrist/eagle-book/lib/perl/Apache/RandomPicture.pm 123): no_cache(1) 
returned @no_cache = (0);%headers_out = ('Cache-control' => 'no-cache','
Pragma' => 'no-cache');


Re: Eagle book RandPicture.pm, $r->internal_redirect, and IE 6.0 showing same image every time

Posted by Michael Peters <mp...@plusthree.com>.
David Christensen wrote:
> Thank you everyone for your thoughts and help.  :-)
> 
> 
> Geoffrey Young wrote:
> 
>>$r->no_cache(1) ...

no_cache() should work (or at least it has for me in the past when IE 
has given me similar headaches).

> dpchrist@p42800e:~$ wget -s -nv http://192.168.254.3/random/picture
> 16:41:15 URL:http://192.168.254.3/random/picture [20831/20831] -> "picture.3"
> [1]
> dpchrist@p42800e:~$ head -n 12 picture.3
> HTTP/1.1 200 OK
> Date: Fri, 01 Jul 2005 23:40:47 GMT
> Server: Apache/1.3.33 (Debian GNU/Linux) mod_perl/1.29
> Last-Modified: Wed, 04 Jun 2003 06:53:10 GMT
> ETag: "1064b-515f-3edd9756;42c4b3fd"
> Accept-Ranges: bytes
> Content-Length: 20831
> Keep-Alive: timeout=15, max=100
> Connection: Keep-Alive
> Content-Type: image/jpeg
> Expires: Fri, 01 Jul 2005 23:40:47 GMT

That's odd. no_cache should not be sending the 'Expires' header. Instead 
it uses the more forceful 'Pragma: no-cache' and 'Cache-control: 
no-cache'. These are not showing up in your headers.

The only thing I can think of is that no_cache(1) is not being executed?

-- 
Michael Peters
Developer
Plus Three, LP


RE: Eagle book RandPicture.pm, $r->internal_redirect, and IE 6.0 showing same image every time

Posted by Frank Maas <fr...@cheiron-it.nl>.
> Frank Maas wrote:
> 
>> What you can try is to update the Last-Modified header on each
>> request. Bear in mind that this won't work for requests that are made
>> within the same second. To probably state the obvious: it is
>> necessary that you set the header to the timestamp of the request,
>> not to the timestamp of the underlying image!
> 
> I'd prefer to get no_cache(1) working, but will keep the various
> date-forcing ideas as backups. 

Well good luck. IMHO no_cache(1) is working fine and is this a client-side
"problem". Webcam viewers have the same problem. There it is solved by 
appending a dummy time-related variable to the request, like

	<img src="/ImageServer/Image&dummy=1234567">

For some browsers the mere fact that the request was made with parameters 
is enough reason to never use it again, for others (that remember the 
complete request) you need to change the value for dummy. There are 
Javascript bits to do this.

Again good luck!

Frank



RE: Eagle book RandPicture.pm, $r->internal_redirect, and IE 6.0 showing same image every time

Posted by David Christensen <dp...@holgerdanske.com>.
Frank Maas wrote:
> You conclude somehwere that IE is not honouring the Expires header,
> but that need not be completely true. The only thing that header is
> telling IE is that it may not _unconditionally_ reuse the same data
> the next time it is needed.  And most probably IE complies to it.
> Since the Expires header tells IE that  the data is "expired" it
> will request the image again. But, different to wget, it will provide
> Apache with the Etag and timestamp of the image it has downloaded the
> last time. Apache then will reply a 304 meaning 'the data you have is
> the same as I have'. This response is based on ETag, URI and timestamp
> of the downloaded image. As you can see in the result of both requests
> (see your data) that information is the same both times.

Sounds plausible.  (If it becomes necessary, perhaps I can snoop the LAN with
Ethereal, etc., to see the differences between wget and IE.)


> What you can try is to update the Last-Modified header on each
> request. Bear in mind that this won't work for requests that are made
> within the same second. To probably state the obvious: it is necessary
> that you set the header to the timestamp of the request, not to the
> timestamp of the underlying image!

I'd prefer to get no_cache(1) working, but will keep the various date-forcing
ideas as backups.


Thanks!

David


RE: Eagle book RandPicture.pm, $r->internal_redirect, and IE 6.0 showing same image every time

Posted by Frank Maas <fr...@cheiron-it.nl>.
Davind,

IMHO the problem is hidden in the headers...:

> dpchrist@p42800e:~$ head -n 12 picture.2
> HTTP/1.1 200 OK
> Date: Fri, 01 Jul 2005 23:36:53 GMT
> Server: Apache/1.3.33 (Debian GNU/Linux) mod_perl/1.29
> Last-Modified: Wed, 04 Jun 2003 06:53:10 GMT
> ETag: "1064b-515f-3edd9756;42c4b3fd"

> "picture.3" [1] dpchrist@p42800e:~$ head -n 12 picture.3
> HTTP/1.1 200 OK
> Date: Fri, 01 Jul 2005 23:40:47 GMT
> Server: Apache/1.3.33 (Debian GNU/Linux) mod_perl/1.29
> Last-Modified: Wed, 04 Jun 2003 06:53:10 GMT
> ETag: "1064b-515f-3edd9756;42c4b3fd"

You conclude somehwere that IE is not honouring the Expires header, but that
need not be completely true. The only thing that header is telling IE is that
it may not _unconditionally_ reuse the same data the next time it is needed.
And most probably IE complies to it. Since the Expires header tells IE that 
the data is "expired" it will request the image again. But, different to wget,
it will provide Apache with the Etag and timestamp of the image it has 
downloaded the last time. Apache then will reply a 304 meaning 'the data you
have is the same as I have'. This response is based on ETag, URI and timestamp
of the downloaded image. As you can see in the result of both requests (see 
your data) that information is the same both times.

What you can try is to update the Last-Modified header on each request. Bear
in mind that this won't work for requests that are made within the same 
second. To probably state the obvious: it is necessary that you set the header
to the timestamp of the request, not to the timestamp of the underlying image!

HTH,

Frank


RE: Eagle book RandPicture.pm, $r->internal_redirect, and IE 6.0 showing same image every time

Posted by David Christensen <dp...@holgerdanske.com>.
Thank you everyone for your thoughts and help.  :-)


Geoffrey Young wrote:
> $r->no_cache(1) ...

That's the kind of answer I was hoping for.  RTFM "perldoc Apache" looks
encouraging.  Implement it (see CVS diff below).  Nope -- IE still displays the
same image every time.  :-(


Let's do some trouble shooting with wget, to see if we can isolate it to the
server or the client:

dpchrist@p42800e:~$ wget http://192.168.254.3/random/picture
--16:13:43--  http://192.168.254.3/random/picture
           => `picture'
Connecting to 192.168.254.3:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 26,720 [image/jpeg]

100%[====================================>] 26,720        --.--K/s

16:13:43 (6.37 MB/s) - `picture' saved [26720/26720]


dpchrist@p42800e:~$ wget http://192.168.254.3/random/picture
--16:14:20--  http://192.168.254.3/random/picture
           => `picture.1'
Connecting to 192.168.254.3:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 20,831 [image/jpeg]

100%[====================================>] 20,831        --.--K/s

16:14:21 (6.62 MB/s) - `picture.1' saved [20831/20831]


Looking at the Apache log on the server:

root@p166v:~# tail -n 15 /var/log/apache-perl/error.log  | grep redirect
[Fri Jul  1 16:13:16 2005] [error] Apache::RandomPicture::handler
(/home/dpchrist/eagle-book/lib/perl/Apache/RandomPicture.pm 117): redirecting to
'/images/2075_2.jpg'
[Fri Jul  1 16:13:53 2005] [error] Apache::RandomPicture::handler
(/home/dpchrist/eagle-book/lib/perl/Apache/RandomPicture.pm 117): redirecting to
'/images/2075_4.jpg'


Apache should have sent 2075_2.jpg and 2075_4.jpg.  Check their sizes:

root@p166v:~# ll /home/dpchrist/eagle-book/images/2075_[24]*
-rw-r--r--  1 dpchrist dpchrist 26720 Jun  3  2003 /home/dpchrist/eagle-book/ima
ges/2075_2.jpg
-rw-r--r--  1 dpchrist dpchrist 20831 Jun  3  2003 /home/dpchrist/eagle-book/ima
ges/2075_4.jpg


Sent files have identical sizes as disk files Apache said it sent.


Do some more digging -- use wget's -s (save-headers) option to see the headers:

dpchrist@p42800e:~$ wget -s http://192.168.254.3/random/picture
--16:37:21--  http://192.168.254.3/random/picture
           => `picture.2'
Connecting to 192.168.254.3:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 20,831 [image/jpeg]

100%[====================================>] 20,831        --.--K/s

16:37:21 (9.93 MB/s) - `picture.2' saved [20831/20831]

dpchrist@p42800e:~$ head -n 12 picture.2
HTTP/1.1 200 OK
Date: Fri, 01 Jul 2005 23:36:53 GMT
Server: Apache/1.3.33 (Debian GNU/Linux) mod_perl/1.29
Last-Modified: Wed, 04 Jun 2003 06:53:10 GMT
ETag: "1064b-515f-3edd9756;42c4b3fd"
Accept-Ranges: bytes
Content-Length: 20831
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Content-Type: image/jpeg
Expires: Fri, 01 Jul 2005 23:36:53 GMT


The "Expires" field seems to be set to the time the document was fetched
(matches the "Date" field).  Try again:

dpchrist@p42800e:~$ wget -s -nv http://192.168.254.3/random/picture
16:41:15 URL:http://192.168.254.3/random/picture [20831/20831] -> "picture.3"
[1]
dpchrist@p42800e:~$ head -n 12 picture.3
HTTP/1.1 200 OK
Date: Fri, 01 Jul 2005 23:40:47 GMT
Server: Apache/1.3.33 (Debian GNU/Linux) mod_perl/1.29
Last-Modified: Wed, 04 Jun 2003 06:53:10 GMT
ETag: "1064b-515f-3edd9756;42c4b3fd"
Accept-Ranges: bytes
Content-Length: 20831
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Content-Type: image/jpeg
Expires: Fri, 01 Jul 2005 23:40:47 GMT


Apache is setting the "Expires" header to the current time each time.  Is IE
ignoring it, or does not understand GMT (?).


Add ".jpg" extensions to the first two files and look at them -- yes, they're
2075_2.jpg and 2075_4.jpg.


Double-check IE settings via Tools -> Internet Options:

1.  Security -> Medium.

2.  Privacy -> Medium.

3.  Advanced -> Restore Defaults.


Shut down client computer.  Gracefully restart server.  Boot client.  Try again.
Same problem.


Fetch /random/picture a couple of times (same image).  Gracefully restart
server.  Try again.  Same problem.


Put the subr->run() implementation back in place.  Gracefully restart server.
Try again.  Now it works.


I think I've given this dead horse a thorough beating -- I think IE 6.0 is the
problem.


The Apache work-around would seem to be $subr->run().


David
--

<CVSENV>dpchrist@p166v:~/eagle-book/lib/perl/Apache$ cvs -q diff -r 1.3 
RandomPicture.pm
Index: RandomPicture.pm
===================================================================
RCS file: /cvs/dpchrist/eagle-book/lib/perl/Apache/RandomPicture.pm,v
retrieving revision 1.3
retrieving revision 1.5
diff -r1.3 -r1.5
2c2
< # $Id: RandomPicture.pm,v 1.3 2005/06/30 03:52:18 dpchrist Exp $
---
> # $Id: RandomPicture.pm,v 1.5 2005/07/01 23:03:27 dpchrist Exp $
114a115,118
>       $r->no_cache(1);
>       $r->log_error(sprintf("%s (%s %s): ",
>           (caller(0))[3], __FILE__, __LINE__),
>           "redirecting to '$lucky_one'");


Re: Eagle book RandPicture.pm, $r->internal_redirect, and IE 6.0 showing same image every time

Posted by Geoffrey Young <ge...@modperlcookbook.org>.

Slava Bizyayev wrote:
> On Thu, 2005-06-30 at 22:52, David Christensen wrote:
> 
>>1.  Make a mod_perl call that tells the browser not to cache the
>>    upcoming document.  (Does such a call exist?)
> 
> 
> Take a look at Expires HTTP header. See rfc2616 for additional details.

  $r->no_cache(1) is probably simpler :)
> 
> 
>>2.  Make a mod_perl call that tells the browser that the upcoming
>>    document is newer than the last one requested (I might be able to
>>    implement this idea using time(), update_mtime(), and
>>    set_last_modified(), but it seems like a crude hack).
> 
> 
> Sounds like an unnecessary hack. 

not necessarily - a bit overblown perhaps, but possibly not an unnecessary
approach.

say the current image in msie has a newer mtime on disk than the image
you're about to redirect to.  in that case an internal_redirect will cause
apache to use the mtime from the redirected file and apache's
default_handler will return 304 - don't forget, internal_redirect is about
fooling the browser by giving it content it didn't actually request.  if you
touch all of your random image files I suspect the image would change.

but it all depends on the effect you want within the browser - if you want
an image to change on each and every request _to the same url_ then yeah,
you need to set no_cache(1) and take possibly other steps to make sure that
no conditional headers are sent with the request.  othersise apache will
send the proper conditional headers for a static file, then msie will cache
those headers and use them to decide what it shows the user.

HTH

--Geoff

RE: Eagle book RandPicture.pm, $r->internal_redirect, and IE 6.0 showing same image every time

Posted by Slava Bizyayev <sb...@outlook.net>.
On Thu, 2005-06-30 at 22:52, David Christensen wrote:
> 1.  Make a mod_perl call that tells the browser not to cache the
>     upcoming document.  (Does such a call exist?)

Take a look at Expires HTTP header. See rfc2616 for additional details.

> 
> 2.  Make a mod_perl call that tells the browser that the upcoming
>     document is newer than the last one requested (I might be able to
>     implement this idea using time(), update_mtime(), and
>     set_last_modified(), but it seems like a crude hack).

Sounds like an unnecessary hack. I would better pay more attention to
possible proxies somewhere on network... See Vary * HTTP header for
details.

Hope this helps,
-- 
Slava Bizyayev
--
Setting the pace for tomorrow's Internet today. Join us and find out
more about the future direction of this widely acknowledged server
software. == ApacheCon 2005 == Stuttgart, Germany 18-22 July 2005
http://apachecon.com/2005/EU/html/sessions.html
Improving Web Performance with Dynamic Compression
The same hardware, just 20 times faster. Friday, 22 July 2005, 10:00
--
slava@apache.org  +44(0)208-923-5913   http://www.dynagzip.com
slava@cpan.org    +44(0)794-766-4131 - mobile AIM: SlavaBizyayev


RE: Eagle book RandPicture.pm, $r->internal_redirect, and IE 6.0 showing same image every time

Posted by David Christensen <dp...@holgerdanske.com>.
Philip M. Gollucci wrote:
> Just for kicks, can you try it in another browser like FireFox ?

A logical suggestion, but:

1.  IE with default security and privacy settings is my target browser.
    If IE has an issue with internal_redirect(), I need to deal with it
    at the mod_perl end.

2.  I have an aversion to installing software on Windows machines --
    the only way to truly get the machine back to the state it was in
    prior to installing the software is to take a Ghost image first,
    install the software, and then do a Ghost restore.  The catch-22 is
    when you install the software, think it's okay, run the box for
    [hours|days|weeks|months], make system changes along the way, and
    then realize that the software must be removed.  Restoring the
    Ghost image means backing up your data first, doing the Ghost
    restore (losing all those changes you made after installing the
    software), re-doing all those changes, and restoring you data.  Not
    restoring means being stuck with any non-uninstallable portions of
    the software and/or any side-effects or artifacts of installing or
    running the software.


I'm wondering if anybody out there has seen this symptom, knows the explanation
why, and can point me towards a good solution.  An Eagle book page reference,
man page reference, perldoc reference, URL, etc. is all I'm looking for.


Some work-arounds come to mind:

1.  Make a mod_perl call that tells the browser not to cache the
    upcoming document.  (Does such a call exist?)

2.  Make a mod_perl call that tells the browser that the upcoming
    document is newer than the last one requested (I might be able to
    implement this idea using time(), update_mtime(), and
    set_last_modified(), but it seems like a crude hack).


David



Re: Eagle book RandPicture.pm, $r->internal_redirect, and IE 6.0 showing same image every time

Posted by "Philip M. Gollucci" <pg...@p6m7g8.com>.
David Christensen wrote:

>modperl:
>
>When I implement the $r->internal_redirect optimization per p. 129 (see source
>code, below), IE 6.0 displays the same image every time, even though
>RandPicture.pm seems to be selecting different images (see debugging information
>in error log, below).
>
>
>I have tried clearing the browser's cache and turning caching off, but the issue
>remains.
>
>
>Any suggestions?
>  
>
Just for kicks, can you try it in another browser like FireFox ?

I looked up the original
http://www.modperl.com/book/source/apachemod-code-1.02/lib/Apache/RandPicture.pm

Nothing popped out at me........



-- 
END 
---------------------------------------------------------
    What doesn't kill us can only make us stronger.
               Nothing is impossible.
				
Philip M. Gollucci (pgollucci@p6m7g8.com) 301.254.5198
Consultant / http://p6m7g8.net/Resume/resume.shtml
Senior Developer / Liquidity Services, Inc.
     http://www.liquidityservicesinc.com
        http://www.liquidation.com
        http://www.uksurplus.com
        http://www.govliquidation.com
        http://www.gowholesale.com