CGI-PSGI
view release on metacpan or search on metacpan
lib/CGI/PSGI.pm view on Meta::CPAN
my($type,$status,$cookie,$target,$expires,$nph,$charset,$attachment,$p3p,@other) =
CGI::rearrange([['TYPE','CONTENT_TYPE','CONTENT-TYPE'],
'STATUS',['COOKIE','COOKIES'],'TARGET',
'EXPIRES','NPH','CHARSET',
'ATTACHMENT','P3P'],@p);
# CR escaping for values, per RFC 822
for my $header ($type,$status,$cookie,$target,$expires,$nph,$charset,$attachment,$p3p,@other) {
if (defined $header) {
# From RFC 822:
# Unfolding is accomplished by regarding CRLF immediately
# followed by a LWSP-char as equivalent to the LWSP-char.
$header =~ s/$CGI::CRLF(\s)/$1/g;
# All other uses of newlines are invalid input.
if ($header =~ m/$CGI::CRLF|\015|\012/) {
# shorten very long values in the diagnostic
$header = substr($header,0,72).'...' if (length $header > 72);
die "Invalid header value contains a newline not followed by whitespace: $header";
}
}
}
$type ||= 'text/html' unless defined($type);
if (defined $charset) {
$self->charset($charset);
} else {
$charset = $self->charset if $type =~ /^text\//;
}
$charset ||= '';
# rearrange() was designed for the HTML portion, so we
# need to fix it up a little.
my @other_headers;
for (@other) {
# Don't use \s because of perl bug 21951
next unless my($header,$value) = /([^ \r\n\t=]+)=\"?(.+?)\"?$/;
$header =~ s/^(\w)(.*)/"\u$1\L$2"/e;
push @other_headers, $header, $self->unescapeHTML($value);
}
$type .= "; charset=$charset"
if $type ne ''
and $type !~ /\bcharset\b/
and defined $charset
and $charset ne '';
# Maybe future compatibility. Maybe not.
my $protocol = $self->{psgi_env}{SERVER_PROTOCOL} || 'HTTP/1.0';
push(@header, "Window-Target", $target) if $target;
if ($p3p) {
$p3p = join ' ',@$p3p if ref($p3p) eq 'ARRAY';
push(@header,"P3P", qq(policyref="/w3c/p3p.xml", CP="$p3p"));
}
# push all the cookies -- there may be several
if ($cookie) {
my(@cookie) = ref($cookie) && ref($cookie) eq 'ARRAY' ? @{$cookie} : $cookie;
for (@cookie) {
my $cs = UNIVERSAL::isa($_,'CGI::Cookie') ? $_->as_string : $_;
push(@header,"Set-Cookie", $cs) if $cs ne '';
}
}
# if the user indicates an expiration time, then we need
# both an Expires and a Date header (so that the browser is
# uses OUR clock)
push(@header,"Expires", CGI::expires($expires,'http'))
if $expires;
push(@header,"Date", CGI::expires(0,'http')) if $expires || $cookie || $nph;
push(@header,"Pragma", "no-cache") if $self->cache();
push(@header,"Content-Disposition", "attachment; filename=\"$attachment\"") if $attachment;
push(@header, @other_headers);
push(@header,"Content-Type", $type) if $type ne '';
$status ||= "200";
$status =~ s/\D*$//;
return $status, \@header;
}
# Ported from CGI.pm's redirect() method.
sub psgi_redirect {
my ($self,@p) = @_;
my($url,$target,$status,$cookie,$nph,@other) =
CGI::rearrange([['LOCATION','URI','URL'],'TARGET','STATUS',['COOKIE','COOKIES'],'NPH'],@p);
$status = '302 Found' unless defined $status;
$url ||= $self->self_url;
my(@o);
for (@other) { tr/\"//d; push(@o,split("=",$_,2)); }
unshift(@o,
'-Status' => $status,
'-Location'=> $url,
'-nph' => $nph);
unshift(@o,'-Target'=>$target) if $target;
unshift(@o,'-Type'=>'');
my @unescaped;
unshift(@unescaped,'-Cookie'=>$cookie) if $cookie;
return $self->psgi_header((map {$self->unescapeHTML($_)} @o),@unescaped);
}
# The list is auto generated and modified with:
# perl -nle '/^sub (\w+)/ and $sub=$1; \
# /^}\s*$/ and do { print $sub if $code{$sub} =~ /([\%\$]ENV|http\()/; undef $sub };\
# $code{$sub} .= "$_\n" if $sub; \
# /^\s*package [^C]/ and exit' \
# `perldoc -l CGI`
for my $method (qw(
url_param
url
cookie
raw_cookie
_name_and_path_from_env
request_method
content_type
path_translated
request_uri
Accept
user_agent
virtual_host
remote_host
remote_addr
referrer
server_name
server_software
virtual_port
server_port
server_protocol
http
https
remote_ident
auth_type
remote_user
user_name
read_multipart
read_multipart_related
)) {
no strict 'refs';
*$method = sub {
my $self = shift;
my $super = "SUPER::$method";
local *ENV = $self->{psgi_env};
$self->$super(@_);
};
}
sub DESTROY {
my $self = shift;
CGI::initialize_globals();
}
1;
__END__
=encoding utf-8
=for stopwords
( run in 1.678 second using v1.01-cache-2.11-cpan-7fcb06a456a )