develooper Front page | perl.perl6.stdlib | Postings from September 2000

RFC 333 (v2) Add C<header> and C<unheader> funtions to core distribution

From:
Perl6 RFC Librarian
Date:
September 29, 2000 14:22
Subject:
RFC 333 (v2) Add C<header> and C<unheader> funtions to core distribution
Message ID:
20000929212238.15587.qmail@tmtowtdi.perl.org
This and other RFCs are available on the web at
  http://dev.perl.org/rfc/

=head1 TITLE

Add C<header> and C<unheader> funtions to core distribution

=head1 VERSION

   Maintainer: Nathan Wiger <nate@wiger.org>
   Date: 27 Sep 2000
   Last Modified: 29 Sep 2000
   Mailing List: perl6-stdlib@perl.org
   Number: 333
   Version: 2
   Status: Frozen

=head1 ABSTRACT

Many services use HTTP-style headers to pass information, including
HTTP, SMTP, and others. These headers, described in internet RFC 822
(see L<REFERENCES>), are a widely-accepted internet standard.

This RFC proposes that Perl include a simple function, C<header>, that
can be used to interact with these headers more easily. It is a
general-purpose formatting function that does not do any
content-specific handling (unlike C<CGI.pm>'s version). It is also
proposed that an C<unheader> function be included which converts in the
opposite direction.

=head1 NOTES ON FREEZE

Since this belongs in a module, and I've already written one, this RFC
basically boils down to just making sure Text::Header (or an equivalent
yet renamed module) ends up in the stdlib. These functions just need to
be available for stuff like the C<use cgi> pragma proposed in B<RFC
288>.

Any additional technical concerns should be addressed towards improving
the module itself.

=head1 DESCRIPTION

The C<header> function works very similarly to C<CGI.pm> and
C<HTTP::Headers>:

   @HEADERS = header(content_type => 'text/html',
                     author => 'Nathan Wiger',
                     last_modified => $date,
                     accept => [qw(text/html text/plain)]);

This would produce an array of the following:

   @HEADERS = ("Content-Type: text/html\n",
               "Author: Nathan Wiger\n",
               "Last-Modified: Wed Sep 27 13:31:06 PDT 2000\n",
               "Accept: text/html, text/plain\n");

Note that unlike C<CGI.pm>, the header function does not end the array
with a singular "\n". The C<header> function would simply:

   1. uc the first letter of each tag token and lc the
      rest, also converting _'s to -'s automatically

   2. Add a colon separating each tag and its value,
      and exactly one newline after each one

   3. Combine list elements into a comma-delimited
      string 

This usage integrates very well with B<RFC 288> on improving the
coupling between Perl and CGI apps. Note that a list is always joined
into a comma-delimited string. To insert multiple separate headers,
simply call C<header> with multiple args:

   push @out, header(accept => 'text/html',
                     accept => 'text/plain');

This would create multiple "Accept:" lines.

Unlike C<CGI.pm>, the C<header> function would B<not> provide any
defaults. If called simply as:

   @HEADERS = header;

C<header> will return an empty list. This allows C<header> to be more
general pupose, so it can provide SMTP and other headers as well:

   @mail_headers = header(from => 'nate@sun.com',
                          to => 'perl6-rfc@perl.org');
   print $MAIL @mail_headers, "\n", @content;

In addition, it is proposed that an C<unheader> function be added as
well. This function would convert in the opposite direction:

   1. lc the entire tag name converting -'s to _'s

   2. Separate each tag based on the colon delimiter,
      chomping newlines.

   3. Return a list of tag/value pairs for easy assignment
      to a hash

So, assuming the C<@HEADERS> array above:

   %myheaders = unheader(@HEADERS);

The hash C<%myheaders> would have the following values:

   %myheaders = (
       content_type => 'text/html',
       author => 'Nathan Wiger',
       last_modified => 'Wed Sep 27 13:31:06 PDT 2000',
       accept => 'text/html, text/plain'
   );

Note that all keys are converted to lowercase, and their values have
their newlines stripped. However, note that comma-separated fields are
not split up on input. This cannot be done reliably because some fields,
such as the HTTP "Date:" header, can contain commas even though they are
not lists. Inferring this type of structure would require knowledge of
content, and these functions are specifically designed to be
content-independent

Since the two functions are inverses, this:

   @out = header unheader @in;

will result in C<@out> being exactly equivalent to C<@in>.

=head1 IMPLEMENTATION

Include C<Text::Header> in the stdlib:
http://www.perl.com/CPAN/modules/by-authors/id/N/NW/NWIGER/Text-Header-1.03.tar.gz

=head1 MIGRATION

This introduces new functionality, but its name does conflict with those
using C<CGI.pm>. However, using both C<CGI.pm> and C<Text::Header> at
the same time would silly, so would probably not happen.

=head1 REFERENCES

RFC 288: First-Class CGI Support

RFC 14:  Modify open() to support FileObjects and Extensibility

C<CGI.pm> by Lincoln Stein

C<HTTP::Headers> by Gisle Aas

http://sunsite.auc.dk/RFC/rfc/rfc822.html




nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About