document %header defaults, attributes, and changing
[perl/plp/.git] / lib / PLP / Fields.pm
1 package PLP::Fields;
2
3 use strict;
4 use warnings;
5
6 our $VERSION = '1.00';
7
8 # Has only one function: doit(), which ties the hashes %get, %post, %fields
9 # and %header in PLP::Script. Also generates %cookie immediately.
10 sub doit {
11
12         # %get
13         
14         my $get = \%PLP::Script::get;
15         if (defined $ENV{QUERY_STRING} and length $ENV{QUERY_STRING}){
16                 for (split /[&;]/, $ENV{QUERY_STRING}) {
17                         my @keyval = split /=/, $_, 2;
18                         PLP::Functions::DecodeURI(@keyval);
19                         $get->{$keyval[0]} = $keyval[1] unless $keyval[0] =~ /^\@/;
20                         push @{ $get->{ '@' . $keyval[0] } }, $keyval[1];
21                 }
22         }
23
24         # %post
25
26         tie %PLP::Script::post, 'PLP::Tie::Delay', 'PLP::Script::post', sub {
27                 my %post;
28                 return \%post unless $ENV{CONTENT_TYPE} and $ENV{CONTENT_LENGTH} and
29                         $ENV{CONTENT_TYPE} =~ m!^(?:application/x-www-form-urlencoded|$)!;
30                 
31                 my $post = $PLP::read->($ENV{CONTENT_LENGTH});
32                 return \%post unless defined $post and length $post;
33                 
34                 for (split /&/, $post) {
35                         my @keyval = split /=/, $_, 2;
36                         PLP::Functions::DecodeURI(@keyval);
37                         $post{$keyval[0]} = $keyval[1] unless $keyval[0] =~ /^\@/;
38                         push @{ $post{ '@' . $keyval[0] } }, $keyval[1];
39                 }
40                 
41                 return \%post;
42         };
43
44         # %fields
45
46         tie %PLP::Script::fields, 'PLP::Tie::Delay', 'PLP::Script::fields', sub {
47                 return { %PLP::Script::get, %PLP::Script::post };
48         };
49
50         # %header
51
52         tie %PLP::Script::header, 'PLP::Tie::Headers';
53
54         # %cookie
55
56         if (defined $ENV{HTTP_COOKIE} and length $ENV{HTTP_COOKIE}) {
57                 for (split /; ?/, $ENV{HTTP_COOKIE}) {
58                         my @keyval = split /=/, $_, 2;
59                         $PLP::Script::cookie{$keyval[0]} ||= $keyval[1];
60                 }
61         }
62 }
63
64 1;
65
66 =head1 NAME
67
68 PLP::Fields - Special hashes for PLP
69
70 =head1 DESCRIPTION
71
72 For your convenience, PLP uses hashes to put things in. Some of these are tied
73 hashes, so they contain a bit magic. For example, building the hash can be
74 delayed until you actually use the hash.
75
76 =over 10
77
78 =item C<%get> and C<%post>
79
80 These are built from the C<key=value&key=value> (or C<key=value;key=value>
81 strings in query string and post content. C<%post> is not built if the content
82 type is not C<application/x-www-form-urlencoded>. In post content, the
83 semi-colon is not a valid separator.
84
85 %post isn't built until it is used, to speed up your script if you
86 don't use it. Because POST content can only be read once, you can C<use CGI;>
87 and just never access C<%post> to avoid its building.
88
89 With a query string of C<key=firstvalue&key=secondvalue>, C<$get{key}> will
90 contain only C<secondvalue>. You can access both elements by using the array
91 reference C<$get{'@key'}>, which will contain C<[ 'firstvalue', 'secondvalue'
92 ]>.
93
94 =item C<%fields>
95
96 This hash combines %get and %post, and triggers creation of %post. POST gets
97 precedence over GET (note: not even the C<@>-keys contain both values).
98
99 This hash is built on first use, just like %post.
100
101 =item C<%cookie>, C<%cookies>
102
103 This is built immediately, because cookies are usually short in length. Cookies
104 are B<not> automatically url-decoded.
105
106 =item C<%header>, C<%headers>
107
108 This is a hash of HTTP headers to accompany the first output.
109 By default it will contain C<X-PLP-Version> to identify the serving module,
110 and C<Content-Type> set to C<text/html>.
111
112 If STDOUT has been opened as :utf8,
113 a C<charset=utf-8> attribute will automatically be added.
114 This will not be possible with FastCGI
115 because FCGI (as of version 0.74) does not support output layers.
116
117 Headers can be added and/or changed as long as they have not yet been sent.
118 Underscores in key names are converted to normal minus signs,
119 so you can leave out quotes.  The hash is case insensitive: the case used
120 when sending the headers is the one you used first. The following are equal:
121
122     $header{CONTENT_TYPE}
123     $header{'Content-Type'}
124     $header{Content_Type}
125     $headers{CONTENT_type}
126
127 If a value contains newlines, the header is repeated for each line:
128
129         $header{Allow} = "HEAD\nGET";  # equivalent to HEAD,GET
130
131 For example, to send out a non-HTML text instead of the default HTML:
132
133     <:
134     $header{content_type} = 'text/plain';
135     use open ':std', ':utf8';
136     :>
137     This text should be prefixed by the following header:
138         Content-Type: text/plain; charset=utf-8
139
140 =back
141
142 =head1 AUTHOR
143
144 Juerd Waalboer <juerd@cpan.org>
145
146 Current maintainer: Mischa POSLAWSKY <shiar@cpan.org>
147
148 =cut
149