Debian lenny version packages
[pkg-perl] / deb-src / libwww-perl / libwww-perl-5.813 / lib / HTTP / Message.pm
1 package HTTP::Message;
2
3 use strict;
4 use vars qw($VERSION $AUTOLOAD);
5 $VERSION = "5.812";
6
7 require HTTP::Headers;
8 require Carp;
9
10 my $CRLF = "\015\012";   # "\r\n" is not portable
11 $HTTP::URI_CLASS ||= $ENV{PERL_HTTP_URI_CLASS} || "URI";
12 eval "require $HTTP::URI_CLASS"; die $@ if $@;
13
14 *_utf8_downgrade = defined(&utf8::downgrade) ?
15     sub {
16         utf8::downgrade($_[0], 1) or
17             Carp::croak("HTTP::Message content must be bytes")
18     }
19     :
20     sub {
21     };
22
23 sub new
24 {
25     my($class, $header, $content) = @_;
26     if (defined $header) {
27         Carp::croak("Bad header argument") unless ref $header;
28         if (ref($header) eq "ARRAY") {
29             $header = HTTP::Headers->new(@$header);
30         }
31         else {
32             $header = $header->clone;
33         }
34     }
35     else {
36         $header = HTTP::Headers->new;
37     }
38     if (defined $content) {
39         _utf8_downgrade($content);
40     }
41     else {
42         $content = '';
43     }
44
45     bless {
46         '_headers' => $header,
47         '_content' => $content,
48     }, $class;
49 }
50
51
52 sub parse
53 {
54     my($class, $str) = @_;
55
56     my @hdr;
57     while (1) {
58         if ($str =~ s/^([^\s:]+)[ \t]*: ?(.*)\n?//) {
59             push(@hdr, $1, $2);
60             $hdr[-1] =~ s/\r\z//;
61         }
62         elsif (@hdr && $str =~ s/^([ \t].*)\n?//) {
63             $hdr[-1] .= "\n$1";
64             $hdr[-1] =~ s/\r\z//;
65         }
66         else {
67             $str =~ s/^\r?\n//;
68             last;
69         }
70     }
71
72     new($class, \@hdr, $str);
73 }
74
75
76 sub clone
77 {
78     my $self  = shift;
79     my $clone = HTTP::Message->new($self->headers,
80                                    $self->content);
81     $clone->protocol($self->protocol);
82     $clone;
83 }
84
85
86 sub clear {
87     my $self = shift;
88     $self->{_headers}->clear;
89     $self->content("");
90     delete $self->{_parts};
91     return;
92 }
93
94
95 sub protocol { shift->_elem('_protocol',  @_); }
96
97 sub content  {
98
99     my $self = $_[0];
100     if (defined(wantarray)) {
101         $self->_content unless exists $self->{_content};
102         my $old = $self->{_content};
103         $old = $$old if ref($old) eq "SCALAR";
104         &_set_content if @_ > 1;
105         return $old;
106     }
107
108     if (@_ > 1) {
109         &_set_content;
110     }
111     else {
112         Carp::carp("Useless content call in void context") if $^W;
113     }
114 }
115
116 sub _set_content {
117     my $self = $_[0];
118     _utf8_downgrade($_[1]);
119     if (!ref($_[1]) && ref($self->{_content}) eq "SCALAR") {
120         ${$self->{_content}} = $_[1];
121     }
122     else {
123         die "Can't set content to be a scalar reference" if ref($_[1]) eq "SCALAR";
124         $self->{_content} = $_[1];
125         delete $self->{_content_ref};
126     }
127     delete $self->{_parts} unless $_[2];
128 }
129
130
131 sub add_content
132 {
133     my $self = shift;
134     $self->_content unless exists $self->{_content};
135     my $chunkref = \$_[0];
136     $chunkref = $$chunkref if ref($$chunkref);  # legacy
137
138     _utf8_downgrade($$chunkref);
139
140     my $ref = ref($self->{_content});
141     if (!$ref) {
142         $self->{_content} .= $$chunkref;
143     }
144     elsif ($ref eq "SCALAR") {
145         ${$self->{_content}} .= $$chunkref;
146     }
147     else {
148         Carp::croak("Can't append to $ref content");
149     }
150     delete $self->{_parts};
151 }
152
153 sub add_content_utf8 {
154     my($self, $buf)  = @_;
155     utf8::upgrade($buf);
156     utf8::encode($buf);
157     $self->add_content($buf);
158 }
159
160 sub content_ref
161 {
162     my $self = shift;
163     $self->_content unless exists $self->{_content};
164     delete $self->{_parts};
165     my $old = \$self->{_content};
166     my $old_cref = $self->{_content_ref};
167     if (@_) {
168         my $new = shift;
169         Carp::croak("Setting content_ref to a non-ref") unless ref($new);
170         delete $self->{_content};  # avoid modifying $$old
171         $self->{_content} = $new;
172         $self->{_content_ref}++;
173     }
174     $old = $$old if $old_cref;
175     return $old;
176 }
177
178
179 sub decoded_content
180 {
181     my($self, %opt) = @_;
182     my $content_ref;
183     my $content_ref_iscopy;
184
185     eval {
186
187         require HTTP::Headers::Util;
188         my($ct, %ct_param);
189         if (my @ct = HTTP::Headers::Util::split_header_words($self->header("Content-Type"))) {
190             ($ct, undef, %ct_param) = @{$ct[-1]};
191             $ct = lc($ct);
192
193             die "Can't decode multipart content" if $ct =~ m,^multipart/,;
194         }
195
196         $content_ref = $self->content_ref;
197         die "Can't decode ref content" if ref($content_ref) ne "SCALAR";
198
199         if (my $h = $self->header("Content-Encoding")) {
200             $h =~ s/^\s+//;
201             $h =~ s/\s+$//;
202             for my $ce (reverse split(/\s*,\s*/, lc($h))) {
203                 next unless $ce || $ce eq "identity";
204                 if ($ce eq "gzip" || $ce eq "x-gzip") {
205                     require Compress::Zlib;
206                     unless ($content_ref_iscopy) {
207                         # memGunzip is documented to destroy its buffer argument
208                         my $copy = $$content_ref;
209                         $content_ref = \$copy;
210                         $content_ref_iscopy++;
211                     }
212                     $content_ref = \Compress::Zlib::memGunzip($$content_ref);
213                     die "Can't gunzip content" unless defined $$content_ref;
214                 }
215                 elsif ($ce eq "x-bzip2") {
216                     require Compress::Bzip2;
217                     $content_ref = Compress::Bzip2::decompress($$content_ref);
218                     die "Can't bunzip content" unless defined $$content_ref;
219                     $content_ref_iscopy++;
220                 }
221                 elsif ($ce eq "deflate") {
222                     require Compress::Zlib;
223                     my $out = Compress::Zlib::uncompress($$content_ref);
224                     unless (defined $out) {
225                         # "Content-Encoding: deflate" is supposed to mean the "zlib"
226                         # format of RFC 1950, but Microsoft got that wrong, so some
227                         # servers sends the raw compressed "deflate" data.  This
228                         # tries to inflate this format.
229                         unless ($content_ref_iscopy) {
230                             # the $i->inflate method is documented to destroy its
231                             # buffer argument
232                             my $copy = $$content_ref;
233                             $content_ref = \$copy;
234                             $content_ref_iscopy++;
235                         }
236
237                         my($i, $status) = Compress::Zlib::inflateInit(
238                             WindowBits => -Compress::Zlib::MAX_WBITS(),
239                         );
240                         my $OK = Compress::Zlib::Z_OK();
241                         die "Can't init inflate object" unless $i && $status == $OK;
242                         ($out, $status) = $i->inflate($content_ref);
243                         if ($status != Compress::Zlib::Z_STREAM_END()) {
244                             if ($status == $OK) {
245                                 $self->push_header("Client-Warning" =>
246                                     "Content might be truncated; incomplete deflate stream");
247                             }
248                             else {
249                                 # something went bad, can't trust $out any more
250                                 $out = undef;
251                             }
252                         }
253                     }
254                     die "Can't inflate content" unless defined $out;
255                     $content_ref = \$out;
256                     $content_ref_iscopy++;
257                 }
258                 elsif ($ce eq "compress" || $ce eq "x-compress") {
259                     die "Can't uncompress content";
260                 }
261                 elsif ($ce eq "base64") {  # not really C-T-E, but should be harmless
262                     require MIME::Base64;
263                     $content_ref = \MIME::Base64::decode($$content_ref);
264                     $content_ref_iscopy++;
265                 }
266                 elsif ($ce eq "quoted-printable") { # not really C-T-E, but should be harmless
267                     require MIME::QuotedPrint;
268                     $content_ref = \MIME::QuotedPrint::decode($$content_ref);
269                     $content_ref_iscopy++;
270                 }
271                 else {
272                     die "Don't know how to decode Content-Encoding '$ce'";
273                 }
274             }
275         }
276
277         if ($ct && $ct =~ m,^text/,,) {
278             my $charset = $opt{charset} || $ct_param{charset} || $opt{default_charset} || "ISO-8859-1";
279             $charset = lc($charset);
280             if ($charset ne "none") {
281                 require Encode;
282                 if (do{my $v = $Encode::VERSION; $v =~ s/_//g; $v} < 2.0901 &&
283                     !$content_ref_iscopy)
284                 {
285                     # LEAVE_SRC did not work before Encode-2.0901
286                     my $copy = $$content_ref;
287                     $content_ref = \$copy;
288                     $content_ref_iscopy++;
289                 }
290                 $content_ref = \Encode::decode($charset, $$content_ref,
291                      ($opt{charset_strict} ? Encode::FB_CROAK() : 0) | Encode::LEAVE_SRC());
292             }
293         }
294     };
295     if ($@) {
296         Carp::croak($@) if $opt{raise_error};
297         return undef;
298     }
299
300     return $opt{ref} ? $content_ref : $$content_ref;
301 }
302
303
304 sub as_string
305 {
306     my($self, $eol) = @_;
307     $eol = "\n" unless defined $eol;
308
309     # The calculation of content might update the headers
310     # so we need to do that first.
311     my $content = $self->content;
312
313     return join("", $self->{'_headers'}->as_string($eol),
314                     $eol,
315                     $content,
316                     (@_ == 1 && length($content) &&
317                      $content !~ /\n\z/) ? "\n" : "",
318                 );
319 }
320
321
322 sub headers            { shift->{'_headers'};                }
323 sub headers_as_string  { shift->{'_headers'}->as_string(@_); }
324
325
326 sub parts {
327     my $self = shift;
328     if (defined(wantarray) && (!exists $self->{_parts} || ref($self->{_content}) eq "SCALAR")) {
329         $self->_parts;
330     }
331     my $old = $self->{_parts};
332     if (@_) {
333         my @parts = map { ref($_) eq 'ARRAY' ? @$_ : $_ } @_;
334         my $ct = $self->content_type || "";
335         if ($ct =~ m,^message/,) {
336             Carp::croak("Only one part allowed for $ct content")
337                 if @parts > 1;
338         }
339         elsif ($ct !~ m,^multipart/,) {
340             $self->remove_content_headers;
341             $self->content_type("multipart/mixed");
342         }
343         $self->{_parts} = \@parts;
344         _stale_content($self);
345     }
346     return @$old if wantarray;
347     return $old->[0];
348 }
349
350 sub add_part {
351     my $self = shift;
352     if (($self->content_type || "") !~ m,^multipart/,) {
353         my $p = HTTP::Message->new($self->remove_content_headers,
354                                    $self->content(""));
355         $self->content_type("multipart/mixed");
356         $self->{_parts} = [$p];
357     }
358     elsif (!exists $self->{_parts} || ref($self->{_content}) eq "SCALAR") {
359         $self->_parts;
360     }
361
362     push(@{$self->{_parts}}, @_);
363     _stale_content($self);
364     return;
365 }
366
367 sub _stale_content {
368     my $self = shift;
369     if (ref($self->{_content}) eq "SCALAR") {
370         # must recalculate now
371         $self->_content;
372     }
373     else {
374         # just invalidate cache
375         delete $self->{_content};
376         delete $self->{_content_ref};
377     }
378 }
379
380
381 # delegate all other method calls the the _headers object.
382 sub AUTOLOAD
383 {
384     my $method = substr($AUTOLOAD, rindex($AUTOLOAD, '::')+2);
385     return if $method eq "DESTROY";
386
387     # We create the function here so that it will not need to be
388     # autoloaded the next time.
389     no strict 'refs';
390     *$method = eval "sub { shift->{'_headers'}->$method(\@_) }";
391     goto &$method;
392 }
393
394
395 # Private method to access members in %$self
396 sub _elem
397 {
398     my $self = shift;
399     my $elem = shift;
400     my $old = $self->{$elem};
401     $self->{$elem} = $_[0] if @_;
402     return $old;
403 }
404
405
406 # Create private _parts attribute from current _content
407 sub _parts {
408     my $self = shift;
409     my $ct = $self->content_type;
410     if ($ct =~ m,^multipart/,) {
411         require HTTP::Headers::Util;
412         my @h = HTTP::Headers::Util::split_header_words($self->header("Content-Type"));
413         die "Assert" unless @h;
414         my %h = @{$h[0]};
415         if (defined(my $b = $h{boundary})) {
416             my $str = $self->content;
417             $str =~ s/\r?\n--\Q$b\E--\r?\n.*//s;
418             if ($str =~ s/(^|.*?\r?\n)--\Q$b\E\r?\n//s) {
419                 $self->{_parts} = [map HTTP::Message->parse($_),
420                                    split(/\r?\n--\Q$b\E\r?\n/, $str)]
421             }
422         }
423     }
424     elsif ($ct eq "message/http") {
425         require HTTP::Request;
426         require HTTP::Response;
427         my $content = $self->content;
428         my $class = ($content =~ m,^(HTTP/.*)\n,) ?
429             "HTTP::Response" : "HTTP::Request";
430         $self->{_parts} = [$class->parse($content)];
431     }
432     elsif ($ct =~ m,^message/,) {
433         $self->{_parts} = [ HTTP::Message->parse($self->content) ];
434     }
435
436     $self->{_parts} ||= [];
437 }
438
439
440 # Create private _content attribute from current _parts
441 sub _content {
442     my $self = shift;
443     my $ct = $self->header("Content-Type") || "multipart/mixed";
444     if ($ct =~ m,^\s*message/,i) {
445         _set_content($self, $self->{_parts}[0]->as_string($CRLF), 1);
446         return;
447     }
448
449     require HTTP::Headers::Util;
450     my @v = HTTP::Headers::Util::split_header_words($ct);
451     Carp::carp("Multiple Content-Type headers") if @v > 1;
452     @v = @{$v[0]};
453
454     my $boundary;
455     my $boundary_index;
456     for (my @tmp = @v; @tmp;) {
457         my($k, $v) = splice(@tmp, 0, 2);
458         if (lc($k) eq "boundary") {
459             $boundary = $v;
460             $boundary_index = @v - @tmp - 1;
461             last;
462         }
463     }
464
465     my @parts = map $_->as_string($CRLF), @{$self->{_parts}};
466
467     my $bno = 0;
468     $boundary = _boundary() unless defined $boundary;
469  CHECK_BOUNDARY:
470     {
471         for (@parts) {
472             if (index($_, $boundary) >= 0) {
473                 # must have a better boundary
474                 $boundary = _boundary(++$bno);
475                 redo CHECK_BOUNDARY;
476             }
477         }
478     }
479
480     if ($boundary_index) {
481         $v[$boundary_index] = $boundary;
482     }
483     else {
484         push(@v, boundary => $boundary);
485     }
486
487     $ct = HTTP::Headers::Util::join_header_words(@v);
488     $self->header("Content-Type", $ct);
489
490     _set_content($self, "--$boundary$CRLF" .
491                         join("$CRLF--$boundary$CRLF", @parts) .
492                         "$CRLF--$boundary--$CRLF",
493                         1);
494 }
495
496
497 sub _boundary
498 {
499     my $size = shift || return "xYzZY";
500     require MIME::Base64;
501     my $b = MIME::Base64::encode(join("", map chr(rand(256)), 1..$size*3), "");
502     $b =~ s/[\W]/X/g;  # ensure alnum only
503     $b;
504 }
505
506
507 1;
508
509
510 __END__
511
512 =head1 NAME
513
514 HTTP::Message - HTTP style message (base class)
515
516 =head1 SYNOPSIS
517
518  use base 'HTTP::Message';
519
520 =head1 DESCRIPTION
521
522 An C<HTTP::Message> object contains some headers and a content body.
523 The following methods are available:
524
525 =over 4
526
527 =item $mess = HTTP::Message->new
528
529 =item $mess = HTTP::Message->new( $headers )
530
531 =item $mess = HTTP::Message->new( $headers, $content )
532
533 This constructs a new message object.  Normally you would want
534 construct C<HTTP::Request> or C<HTTP::Response> objects instead.
535
536 The optional $header argument should be a reference to an
537 C<HTTP::Headers> object or a plain array reference of key/value pairs.
538 If an C<HTTP::Headers> object is provided then a copy of it will be
539 embedded into the constructed message, i.e. it will not be owned and
540 can be modified afterwards without affecting the message.
541
542 The optional $content argument should be a string of bytes.
543
544 =item $mess = HTTP::Message->parse( $str )
545
546 This constructs a new message object by parsing the given string.
547
548 =item $mess->headers
549
550 Returns the embedded C<HTTP::Headers> object.
551
552 =item $mess->headers_as_string
553
554 =item $mess->headers_as_string( $eol )
555
556 Call the as_string() method for the headers in the
557 message.  This will be the same as
558
559     $mess->headers->as_string
560
561 but it will make your program a whole character shorter :-)
562
563 =item $mess->content
564
565 =item $mess->content( $bytes )
566
567 The content() method sets the raw content if an argument is given.  If no
568 argument is given the content is not touched.  In either case the
569 original raw content is returned.
570
571 Note that the content should be a string of bytes.  Strings in perl
572 can contain characters outside the range of a byte.  The C<Encode>
573 module can be used to turn such strings into a string of bytes.
574
575 =item $mess->add_content( $bytes )
576
577 The add_content() methods appends more data bytes to the end of the
578 current content buffer.
579
580 =item $mess->add_content_utf8( $string )
581
582 The add_content_utf8() method appends the UTF-8 bytes representing the
583 string to the end of the current content buffer.
584
585 =item $mess->content_ref
586
587 =item $mess->content_ref( \$bytes )
588
589 The content_ref() method will return a reference to content buffer string.
590 It can be more efficient to access the content this way if the content
591 is huge, and it can even be used for direct manipulation of the content,
592 for instance:
593
594   ${$res->content_ref} =~ s/\bfoo\b/bar/g;
595
596 This example would modify the content buffer in-place.
597
598 If an argument is passed it will setup the content to reference some
599 external source.  The content() and add_content() methods
600 will automatically dereference scalar references passed this way.  For
601 other references content() will return the reference itself and
602 add_content() will refuse to do anything.
603
604 =item $mess->decoded_content( %options )
605
606 Returns the content with any C<Content-Encoding> undone and the raw
607 content encoded to perl's Unicode strings.  If the C<Content-Encoding>
608 or C<charset> of the message is unknown this method will fail by
609 returning C<undef>.
610
611 The following options can be specified.
612
613 =over
614
615 =item C<charset>
616
617 This override the charset parameter for text content.  The value
618 C<none> can used to suppress decoding of the charset.
619
620 =item C<default_charset>
621
622 This override the default charset of "ISO-8859-1".
623
624 =item C<charset_strict>
625
626 Abort decoding if malformed characters is found in the content.  By
627 default you get the substitution character ("\x{FFFD}") in place of
628 malformed characters.
629
630 =item C<raise_error>
631
632 If TRUE then raise an exception if not able to decode content.  Reason
633 might be that the specified C<Content-Encoding> or C<charset> is not
634 supported.  If this option is FALSE, then decoded_content() will return
635 C<undef> on errors, but will still set $@.
636
637 =item C<ref>
638
639 If TRUE then a reference to decoded content is returned.  This might
640 be more efficient in cases where the decoded content is identical to
641 the raw content as no data copying is required in this case.
642
643 =back
644
645 =item $mess->parts
646
647 =item $mess->parts( @parts )
648
649 =item $mess->parts( \@parts )
650
651 Messages can be composite, i.e. contain other messages.  The composite
652 messages have a content type of C<multipart/*> or C<message/*>.  This
653 method give access to the contained messages.
654
655 The argumentless form will return a list of C<HTTP::Message> objects.
656 If the content type of $msg is not C<multipart/*> or C<message/*> then
657 this will return the empty list.  In scalar context only the first
658 object is returned.  The returned message parts should be regarded as
659 are read only (future versions of this library might make it possible
660 to modify the parent by modifying the parts).
661
662 If the content type of $msg is C<message/*> then there will only be
663 one part returned.
664
665 If the content type is C<message/http>, then the return value will be
666 either an C<HTTP::Request> or an C<HTTP::Response> object.
667
668 If an @parts argument is given, then the content of the message will be
669 modified. The array reference form is provided so that an empty list
670 can be provided.  The @parts array should contain C<HTTP::Message>
671 objects.  The @parts objects are owned by $mess after this call and
672 should not be modified or made part of other messages.
673
674 When updating the message with this method and the old content type of
675 $mess is not C<multipart/*> or C<message/*>, then the content type is
676 set to C<multipart/mixed> and all other content headers are cleared.
677
678 This method will croak if the content type is C<message/*> and more
679 than one part is provided.
680
681 =item $mess->add_part( $part )
682
683 This will add a part to a message.  The $part argument should be
684 another C<HTTP::Message> object.  If the previous content type of
685 $mess is not C<multipart/*> then the old content (together with all
686 content headers) will be made part #1 and the content type made
687 C<multipart/mixed> before the new part is added.  The $part object is
688 owned by $mess after this call and should not be modified or made part
689 of other messages.
690
691 There is no return value.
692
693 =item $mess->clear
694
695 Will clear the headers and set the content to the empty string.  There
696 is no return value
697
698 =item $mess->protocol
699
700 =item $mess->protocol( $proto )
701
702 Sets the HTTP protocol used for the message.  The protocol() is a string
703 like C<HTTP/1.0> or C<HTTP/1.1>.
704
705 =item $mess->clone
706
707 Returns a copy of the message object.
708
709 =item $mess->as_string
710
711 =item $mess->as_string( $eol )
712
713 Returns the message formatted as a single string.
714
715 The optional $eol parameter specifies the line ending sequence to use.
716 The default is "\n".  If no $eol is given then as_string will ensure
717 that the returned string is newline terminated (even when the message
718 content is not).  No extra newline is appended if an explicit $eol is
719 passed.
720
721 =back
722
723 All methods unknown to C<HTTP::Message> itself are delegated to the
724 C<HTTP::Headers> object that is part of every message.  This allows
725 convenient access to these methods.  Refer to L<HTTP::Headers> for
726 details of these methods:
727
728     $mess->header( $field => $val )
729     $mess->push_header( $field => $val )
730     $mess->init_header( $field => $val )
731     $mess->remove_header( $field )
732     $mess->remove_content_headers
733     $mess->header_field_names
734     $mess->scan( \&doit )
735
736     $mess->date
737     $mess->expires
738     $mess->if_modified_since
739     $mess->if_unmodified_since
740     $mess->last_modified
741     $mess->content_type
742     $mess->content_encoding
743     $mess->content_length
744     $mess->content_language
745     $mess->title
746     $mess->user_agent
747     $mess->server
748     $mess->from
749     $mess->referer
750     $mess->www_authenticate
751     $mess->authorization
752     $mess->proxy_authorization
753     $mess->authorization_basic
754     $mess->proxy_authorization_basic
755
756 =head1 COPYRIGHT
757
758 Copyright 1995-2004 Gisle Aas.
759
760 This library is free software; you can redistribute it and/or
761 modify it under the same terms as Perl itself.
762