X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FCGI%2FPush.pm;h=6b8e012a1528a433181501fd04745aa7aeaa0d15;hb=4b19af017623bfa3bb72bb164598a517f586e0d3;hp=4390d0383e66126d59931af40e8bcbb10e918d13;hpb=3e3baf6d63945cb64e829d6e5c70a7d00f3d3d03;p=p5sagit%2Fp5-mst-13.2.git diff --git a/lib/CGI/Push.pm b/lib/CGI/Push.pm index 4390d03..6b8e012 100644 --- a/lib/CGI/Push.pm +++ b/lib/CGI/Push.pm @@ -14,31 +14,35 @@ package CGI::Push; # listing the modifications you have made. # The most recent version and complete docs are available at: -# http://www.genome.wi.mit.edu/ftp/pub/software/WWW/cgi_docs.html -# ftp://ftp-genome.wi.mit.edu/pub/software/WWW/ +# http://stein.cshl.org/WWW/software/CGI/ -$CGI::Push::VERSION='1.00'; +$CGI::Push::VERSION='1.02'; use CGI; +use CGI::Util 'rearrange'; @ISA = ('CGI'); -# add do_push() to exported tags -push(@{$CGI::EXPORT_TAGS{':standard'}},'do_push'); +$CGI::DefaultClass = 'CGI::Push'; +$CGI::Push::AutoloadClass = 'CGI'; + +# add do_push() and push_delay() to exported tags +push(@{$CGI::EXPORT_TAGS{':standard'}},'do_push','push_delay'); sub do_push { - my ($self,@p) = CGI::self_or_CGI(@_); + my ($self,@p) = CGI::self_or_default(@_); # unbuffer output $| = 1; srand; - my ($random) = rand()*1E16; + my ($random) = sprintf("%16.0f",rand()*1E16); my ($boundary) = "----------------------------------$random"; my (@header); my ($type,$callback,$delay,$last_page,$cookie,$target,$expires,@other) = - $self->rearrange([TYPE,NEXT_PAGE,DELAY,LAST_PAGE,[COOKIE,COOKIES],TARGET,EXPIRES],@p); + rearrange([TYPE,NEXT_PAGE,DELAY,LAST_PAGE,[COOKIE,COOKIES],TARGET,EXPIRES],@p); $type = 'text/html' unless $type; $callback = \&simple_counter unless $callback && ref($callback) eq 'CODE'; $delay = 1 unless defined($delay); + $self->push_delay($delay); my(@o); foreach (@other) { push(@o,split("=")); } @@ -50,20 +54,23 @@ sub do_push { push(@o,'-nph'=>1); print $self->header(@o); print "${boundary}$CGI::CRLF"; - + # now we enter a little loop my @contents; while (1) { last unless (@contents = &$callback($self,++$COUNTER)) && defined($contents[0]); - print "Content-type: ${type}$CGI::CRLF$CGI::CRLF"; + print "Content-type: ${type}$CGI::CRLF$CGI::CRLF" + unless $type eq 'dynamic'; print @contents,"$CGI::CRLF"; print "${boundary}$CGI::CRLF"; - do_sleep($delay) if $delay; + do_sleep($self->push_delay()) if $self->push_delay(); + } + + # Optional last page + if ($last_page && ref($last_page) eq 'CODE') { + print "Content-type: ${type}$CGI::CRLF$CGI::CRLF" unless $type =~ /^dynamic|heterogeneous$/i; + print &$last_page($self,$COUNTER),"$CGI::CRLF${boundary}$CGI::CRLF"; } - print "Content-type: ${type}$CGI::CRLF$CGI::CRLF", - &$last_page($self,++$COUNTER), - "$CGI::CRLF${boundary}$CGI::CRLF" - if $last_page && ref($last_page) eq 'CODE'; } sub simple_counter { @@ -87,6 +94,12 @@ sub do_sleep { } } +sub push_delay { + my ($self,$delay) = CGI::self_or_default(@_); + return defined($delay) ? $self->{'.delay'} = + $delay : $self->{'.delay'}; +} + 1; =head1 NAME @@ -131,6 +144,9 @@ in such a way that it will replace what was there beforehand. The technique will work with HTML pages as well as with graphics files, allowing you to create animated GIFs. +Only Netscape Navigator supports server push. Internet Explorer +browsers do not. + =head1 USING CGI::Push CGI::Push adds one new method to the standard CGI suite, do_push(). @@ -176,6 +192,9 @@ redrawing loop and print out the final page (if any) "This page called $counter times"; } +You are of course free to refer to create and use global variables +within your draw routine in order to achieve special effects. + =item -last_page This optional parameter points to a reference to the subroutine @@ -187,8 +206,12 @@ itself should have exactly the same calling conventions as the =item -type This optional parameter indicates the content type of each page. It -defaults to "text/html". Currently, server push of heterogeneous -document types is not supported. +defaults to "text/html". Normally the module assumes that each page +is of a homogenous MIME type. However if you provide either of the +magic values "heterogeneous" or "dynamic" (the latter provided for the +convenience of those who hate long parameter names), you can specify +the MIME type -- and other header fields -- on a per-page basis. See +"heterogeneous pages" for more details. =item -delay @@ -204,6 +227,60 @@ CGI::header(). =back +=head2 Heterogeneous Pages + +Ordinarily all pages displayed by CGI::Push share a common MIME type. +However by providing a value of "heterogeneous" or "dynamic" in the +do_push() -type parameter, you can specify the MIME type of each page +on a case-by-case basis. + +If you use this option, you will be responsible for producing the +HTTP header for each page. Simply modify your draw routine to +look like this: + + sub my_draw_routine { + my($q,$counter) = @_; + return header('text/html'), # note we're producing the header here + start_html('testing'), + h1('testing'), + "This page called $counter times"; + } + +You can add any header fields that you like, but some (cookies and +status fields included) may not be interpreted by the browser. One +interesting effect is to display a series of pages, then, after the +last page, to redirect the browser to a new URL. Because redirect() +does b work, the easiest way is with a -refresh header field, +as shown below: + + sub my_draw_routine { + my($q,$counter) = @_; + return undef if $counter > 10; + return header('text/html'), # note we're producing the header here + start_html('testing'), + h1('testing'), + "This page called $counter times"; + } + + sub my_last_page { + header(-refresh=>'5; URL=http://somewhere.else/finished.html', + -type=>'text/html'), + start_html('Moved'), + h1('This is the last page'), + 'Goodbye!' + hr, + end_html; + } + +=head2 Changing the Page Delay on the Fly + +If you would like to control the delay between pages on a page-by-page +basis, call push_delay() from within your draw routine. push_delay() +takes a single numeric argument representing the number of seconds you +wish to delay after the current page is displayed and before +displaying the next one. The delay may be fractional. Without +parameters, push_delay() just returns the current delay. + =head1 INSTALLING CGI::Push SCRIPTS Server push scripts B be installed as no-parsed-header (NPH) @@ -213,19 +290,14 @@ Recognition of NPH scripts happens automatically with WebSTAR and Microsoft IIS. Users of other servers should see their documentation for help. -=head1 CAVEATS - -This is a new module. It hasn't been extensively tested. - =head1 AUTHOR INFORMATION -be used and modified freely, but I do request that this copyright -notice remain attached to the file. You may modify this module as you -wish, but if you redistribute a modified version, please attach a note -listing the modifications you have made. +Copyright 1995-1998, Lincoln D. Stein. All rights reserved. + +This library is free software; you can redistribute it and/or modify +it under the same terms as Perl itself. -Address bug reports and comments to: -lstein@genome.wi.mit.edu +Address bug reports and comments to: lstein@cshl.org =head1 BUGS