CGI-Buffer

 view release on metacpan or  search on metacpan

lib/CGI/Buffer.pm  view on Meta::CPAN

	}
	if($generate_etag && ((!defined($headers)) || ($headers !~ /^ETag: /m))) {
		if(defined($etag)) {
			push @o, "ETag: $etag";
			if($logger) {
				$logger->debug("Set ETag to $etag");
			}
		} elsif($logger && (($status == 200) || $status == 304) && $body && !is_cached()) {
			$logger->warn("BUG: ETag not generated, status $status");
		}
	}

	my $body_length;
	if(defined($body)) {
		if(utf8::is_utf8($body)) {
			utf8::encode($body);
		}
		$body_length = length($body);
	} else {
		$body_length = 0;
	}

	if(defined($headers) && length($headers)) {
		# Put the original headers first, then those generated within
		# CGI::Buffer
		unshift @o, split(/\r\n/, $headers);
		if($body && $send_body) {
			if(scalar(grep(/^Content-Length: \d/, @o)) == 0) {
				push @o, "Content-Length: $body_length";
			}
		}
		if(scalar(grep(/^Status: \d/, @o)) == 0) {
			require HTTP::Status;
			HTTP::Status->import();

			push @o, "Status: $status " . HTTP::Status::status_message($status);
			if($info) {
				$info->status($status);
			}
		}
	} else {
		push @o, "X-CGI-Buffer-$VERSION: No headers";
	}

	if($body_length && $send_body) {
		push @o, ('', $body);
	}

	# XXXXXXXXXXXXXXXXXXXXXXX
	if(0) {
		# This code helps to debug Wide character prints
		my $wideCharWarningsIssued = 0;
		my $widemess;
		$SIG{__WARN__} = sub {
			$wideCharWarningsIssued += "@_" =~ /Wide character in .../;
			$widemess = "@_";
			if($logger) {
				$logger->fatal($widemess);
				my $i = 1;
				$logger->trace('Stack Trace');
				while((my @call_details = (caller($i++)))) {
					$logger->trace($call_details[1] . ':' . $call_details[2] . ' in function ' . $call_details[3]);
				}
			}
			CORE::warn(@_);	# call the builtin warn as usual
		};

		if(scalar @o) {
			print join("\r\n", @o);
			if($wideCharWarningsIssued) {
				my $mess = join("\r\n", @o);
				$mess =~ /[^\x00-\xFF]/;
				open(my $fout, '>>', '/tmp/NJH');
				print $fout "$widemess:\n";
				print $fout $mess;
				print $fout 'x' x 40, "\n";
				close $fout;
			}
		}
	} elsif(scalar @o) {
		print join("\r\n", @o);
	}
	# XXXXXXXXXXXXXXXXXXXXXXX

	if((!$send_body) || !defined($body)) {
		print "\r\n\r\n";
	}
}

sub _check_modified_since {
	if($logger) {
		$logger->trace('In _check_modified_since');
	}

	if(!$generate_304) {
		return;
	}
	my $params = shift;

	if(!defined($$params{since})) {
		return;
	}
	my $s = HTTP::Date::str2time($$params{since});
	if(!defined($s)) {
		# IF_MODIFIED_SINCE isn't a valid data
		return;
	}

	my $age = _my_age();
	if(!defined($age)) {
		return;
	}
	if($age > $s) {
		if($logger) {
			$logger->debug('_check_modified_since: script has been modified');
		}
		# Script has been updated so it may produce different output
		return;
	}

	if($logger) {

lib/CGI/Buffer.pm  view on Meta::CPAN


Items stay in the server-side cache by default for 10 minutes.
This can be overridden by the cache_control HTTP header in the request, and
the default can be changed by the cache_duration argument to init().

Logger will be an object that understands debug() such as an L<Log::Log4perl>
object.

To generate a last_modified header, you must give a cache object.

Init allows a reference of the options to be passed. So both of these work:
    use CGI::Buffer;
    #...
    CGI::Buffer::init(generate_etag => 1);
    CGI::Buffer::init({ generate_etag => 1, info => CGI::Info->new() });

Generally speaking, passing by reference is better since it copies less on to
the stack.

Alternatively you can give the options when loading the package:
    use CGI::Buffer { optimise_content => 1 };

=cut

sub init {
	my %params = (ref($_[0]) eq 'HASH') ? %{$_[0]} : @_;

	# Safe options - can be called at any time
	if(defined($params{generate_etag})) {
		$generate_etag = $params{generate_etag};
	}
	if(defined($params{generate_last_modified})) {
		$generate_last_modified = $params{generate_last_modified};
	}
	if(defined($params{compress_content})) {
		$compress_content = $params{compress_content};
	}
	if(defined($params{optimise_content})) {
		$optimise_content = $params{optimise_content};
	}
	if(defined($params{lint_content})) {
		$lint_content = $params{lint_content};
	}
	if(defined($params{logger})) {
		$logger = $params{logger};
	}
	if(defined($params{lingua})) {
		$lingua = $params{lingua};
	}
	if(defined($params{generate_304})) {
		$generate_304 = $params{generate_304};
	}
	if(defined($params{info}) && (!defined($info))) {
		$info = $params{info};
	}

	# Unsafe options - must be called before output has been started
	my $pos = $CGI::Buffer::buf->getpos;
	if($pos > 0) {
		if(defined($logger)) {
			my @call_details = caller(0);
			$logger->warn("Too late to call init, $pos characters have been printed, caller line $call_details[2] of $call_details[1]");
		} else {
			# Must do Carp::carp instead of carp for Test::Carp
			Carp::carp "Too late to call init, $pos characters have been printed";
		}
	}
	if(defined($params{cache}) && can_cache()) {
		if(defined($ENV{'HTTP_CACHE_CONTROL'})) {
			my $control = $ENV{'HTTP_CACHE_CONTROL'};
			if(defined($logger)) {
				$logger->debug("cache_control = $control");
			}
			if($control =~ /^max-age\s*=\s*(\d+)$/) {
				# There is an argument not to do this
				# since one client will affect others
				$cache_duration = "$1 seconds";
				if(defined($logger)) {
					$logger->debug("cache_duration = $cache_duration");
				}
			}
		}
		$cache_duration ||= $params{'cache_duration'};

		if($params{'cache_age'}) {
			# Legacy
			$cache_duration ||= $params{'cache_age'};
		}

		if((!defined($params{cache})) && defined($cache)) {
			if(defined($logger)) {
				if($cache_key) {
					$logger->debug("disabling cache $cache_key");
				} else {
					$logger->debug('disabling cache');
				}
			}
			$cache = undef;
		} else {
			$cache = $params{cache};
		}
		if(defined($params{cache_key})) {
			$cache_key = $params{cache_key};
		}
	}
}

sub import {
	# my $class = shift;
	shift;

	return unless @_;

	init(@_);
}

=head2 set_options

Synonym for init, kept for historical reasons.

=cut



( run in 2.180 seconds using v1.01-cache-2.11-cpan-98e64b0badf )