package PLP::Tie::Headers; use strict; use warnings; use Carp; our $VERSION = '1.01'; =head1 PLP::Tie::Headers Makes a hash case insensitive, and sets some headers. <_> equals <->, so C<$foo{CONTENT_TYPE}> is the same as C<$foo{'Content-Type'}>. tie %somehash, 'PLP::Tie::Headers'; This module is part of the PLP internals and probably not of much use to others. =cut sub TIEHASH { return bless [ # Defaults { 'Content-Type' => 'text/html', 'X-PLP-Version' => $PLP::VERSION, }, { 'content-type' => 'Content-Type', 'x-plp-version' => 'X-PLP-Version', }, 1 # = content-type untouched ], $_[0]; } sub FETCH { my ($self, $key) = @_; if ($self->[2] and defined $self->[0]->{'Content-Type'}) { my $utf8 = eval { grep {$_ eq "utf8"} PerlIO::get_layers(*STDOUT) }; $self->[0]->{'Content-Type'} .= '; charset=utf-8' if $utf8; $self->[2] = 0; } $key =~ tr/_/-/; defined ($key = $self->[1]->{lc $key}) or return; return $self->[0]->{$key}; } sub STORE { my ($self, $key, $value) = @_; $key =~ tr/_/-/; if ($PLP::sentheaders) { my @caller = caller; die "Can't set headers after sending them at " . "$caller[1] line $caller[2].\n(Output started at " . "$PLP::sentheaders->[0] line $PLP::sentheaders->[1].)\n" } if (defined $self->[1]->{lc $key}){ $key = $self->[1]->{lc $key}; } else { $self->[1]->{lc $key} = $key; } $self->[2] = 0 if $key eq 'Content-Type'; return ($self->[0]->{$key} = $value); } sub DELETE { my ($self, $key) = @_; $key =~ tr/_/-/; defined ($key = delete $self->[1]->{lc $key}) or return; return delete $self->[0]->{$key}; } sub CLEAR { my $self = $_[0]; return (@$self = ()); } sub EXISTS { my ($self, $key) = @_; $key =~ tr/_/-/; return exists $self->[1]->{lc $key}; } sub FIRSTKEY { my $self = $_[0]; keys %{$self->[0]}; return each %{ $self->[0] }; # Key only, Tie::Hash doc is wrong. } sub NEXTKEY { return each %{ $_[0]->[0] }; } 1;