ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent-HTTP/HTTP.pm
(Generate patch)

Comparing AnyEvent-HTTP/HTTP.pm (file contents):
Revision 1.83 by root, Sun Jan 2 05:02:28 2011 UTC vs.
Revision 1.84 by root, Sun Jan 2 05:13:27 2011 UTC

777 }; 777 };
778 778
779 $ae_error = 597; # body phase 779 $ae_error = 597; # body phase
780 780
781 my $len = $hdr{"content-length"}; 781 my $len = $hdr{"content-length"};
782 warn "no content $redirect x<$len>$hdr{Status}\n";#d#
782 783
784 # body handling, many different code paths
785 # - no body expected
786 # - want_body_handle
787 # - te chunked
788 # - 2x length known (with or without on_body)
789 # - 2x length not known (with or without on_body)
783 if (!$redirect && $arg{on_header} && !$arg{on_header}(\%hdr)) { 790 if (!$redirect && $arg{on_header} && !$arg{on_header}(\%hdr)) {
784 $finish->(undef, 598 => "Request cancelled by on_header"); 791 $finish->(undef, 598 => "Request cancelled by on_header");
785 } elsif ( 792 } elsif (
786 $hdr{Status} =~ /^(?:1..|204|205|304)$/ 793 $hdr{Status} =~ /^(?:1..|204|205|304)$/
787 or $method eq "HEAD" 794 or $method eq "HEAD"
788 or (defined $len && !$len) 795 or (defined $len && $len == 0) # == 0, not !, because "0 " is true
789 ) { 796 ) {
790 # no body 797 # no body
791 $finish->("", undef, undef, 1); 798 $finish->("", undef, undef, 1);
792 } else { 799
793 # body handling, many different code paths
794 # - no body expected
795 # - want_body_handle
796 # - te chunked
797 # - 2x length known (with or without on_body)
798 # - 2x length not known (with or without on_body)
799 if (!$redirect && $arg{want_body_handle}) { 800 } elsif (!$redirect && $arg{want_body_handle}) {
800 $_[0]->on_eof (undef); 801 $_[0]->on_eof (undef);
801 $_[0]->on_error (undef); 802 $_[0]->on_error (undef);
802 $_[0]->on_read (undef); 803 $_[0]->on_read (undef);
803 804
804 $finish->(delete $state{handle}); 805 $finish->(delete $state{handle});
805 806
806 } elsif ($hdr{"transfer-encoding"} =~ /\bchunked\b/i) { 807 } elsif ($hdr{"transfer-encoding"} =~ /\bchunked\b/i) {
807 my $cl = 0; 808 my $cl = 0;
808 my $body = undef; 809 my $body = undef;
809 my $on_body = $arg{on_body} || sub { $body .= shift; 1 }; 810 my $on_body = $arg{on_body} || sub { $body .= shift; 1 };
810 811
811 $state{read_chunk} = sub { 812 $state{read_chunk} = sub {
812 $_[1] =~ /^([0-9a-fA-F]+)/ 813 $_[1] =~ /^([0-9a-fA-F]+)/
813 or $finish->(undef, $ae_error => "Garbled chunked transfer encoding"); 814 or $finish->(undef, $ae_error => "Garbled chunked transfer encoding");
814 815
815 my $len = hex $1; 816 my $len = hex $1;
816 817
817 if ($len) { 818 if ($len) {
818 $cl += $len; 819 $cl += $len;
819 820
820 $_[0]->push_read (chunk => $len, sub { 821 $_[0]->push_read (chunk => $len, sub {
821 $on_body->($_[1], \%hdr) 822 $on_body->($_[1], \%hdr)
822 or return $finish->(undef, 598 => "Request cancelled by on_body"); 823 or return $finish->(undef, 598 => "Request cancelled by on_body");
823 824
824 $_[0]->push_read (line => sub { 825 $_[0]->push_read (line => sub {
825 length $_[1] 826 length $_[1]
826 and return $finish->(undef, $ae_error => "Garbled chunked transfer encoding"); 827 and return $finish->(undef, $ae_error => "Garbled chunked transfer encoding");
827 $_[0]->push_read (line => $state{read_chunk}); 828 $_[0]->push_read (line => $state{read_chunk});
828 });
829 }); 829 });
830 } else {
831 $hdr{"content-length"} ||= $cl;
832
833 $_[0]->push_read (line => $qr_nlnl, sub {
834 if (length $_[1]) {
835 for ("$_[1]") {
836 y/\015//d; # weed out any \015, as they show up in the weirdest of places.
837
838 my $hdr = parse_hdr
839 or return $finish->(undef, $ae_error => "Garbled response trailers");
840
841 %hdr = (%hdr, %$hdr);
842 }
843 }
844
845 $finish->($body, undef, undef, 1);
846 });
847 }
848 };
849
850 $_[0]->push_read (line => $state{read_chunk});
851
852 } elsif ($arg{on_body}) {
853 if ($len) {
854 $_[0]->on_read (sub {
855 $len -= length $_[0]{rbuf};
856
857 $arg{on_body}(delete $_[0]{rbuf}, \%hdr)
858 or return $finish->(undef, 598 => "Request cancelled by on_body");
859
860 $len > 0
861 or $finish->("", undef, undef, 1);
862 }); 830 });
863 } else { 831 } else {
864 $_[0]->on_eof (sub { 832 $hdr{"content-length"} ||= $cl;
865 $finish->(""); 833
834 $_[0]->push_read (line => $qr_nlnl, sub {
835 if (length $_[1]) {
836 for ("$_[1]") {
837 y/\015//d; # weed out any \015, as they show up in the weirdest of places.
838
839 my $hdr = parse_hdr
840 or return $finish->(undef, $ae_error => "Garbled response trailers");
841
842 %hdr = (%hdr, %$hdr);
843 }
866 }); 844 }
867 $_[0]->on_read (sub { 845
868 $arg{on_body}(delete $_[0]{rbuf}, \%hdr) 846 $finish->($body, undef, undef, 1);
869 or $finish->(undef, 598 => "Request cancelled by on_body");
870 }); 847 });
871 } 848 }
849 };
850
851 $_[0]->push_read (line => $state{read_chunk});
852
853 } elsif ($arg{on_body}) {
854 if (defined $len) {
855 $_[0]->on_read (sub {
856 $len -= length $_[0]{rbuf};
857
858 $arg{on_body}(delete $_[0]{rbuf}, \%hdr)
859 or return $finish->(undef, 598 => "Request cancelled by on_body");
860
861 $len > 0
862 or $finish->("", undef, undef, 1);
863 });
872 } else { 864 } else {
873 $_[0]->on_eof (undef); 865 $_[0]->on_eof (sub {
874 866 $finish->("");
875 if ($len) { 867 });
876 $_[0]->on_read (sub { 868 $_[0]->on_read (sub {
869 $arg{on_body}(delete $_[0]{rbuf}, \%hdr)
870 or $finish->(undef, 598 => "Request cancelled by on_body");
871 });
872 }
873 } else {
874 $_[0]->on_eof (undef);
875
876 if (defined $len) {
877 $_[0]->on_read (sub {
877 $finish->((substr delete $_[0]{rbuf}, 0, $len, ""), undef, undef, 1) 878 $finish->((substr delete $_[0]{rbuf}, 0, $len, ""), undef, undef, 1)
878 if $len <= length $_[0]{rbuf}; 879 if $len <= length $_[0]{rbuf};
879 }); 880 });
880 } else { 881 } else {
881 $_[0]->on_error (sub { 882 $_[0]->on_error (sub {
882 ($! == Errno::EPIPE || !$!) 883 ($! == Errno::EPIPE || !$!)
883 ? $finish->(delete $_[0]{rbuf}) 884 ? $finish->(delete $_[0]{rbuf})
884 : $finish->(undef, $ae_error => $_[2]); 885 : $finish->(undef, $ae_error => $_[2]);
885 }); 886 });
886 $_[0]->on_read (sub { }); 887 $_[0]->on_read (sub { });
887 }
888 } 888 }
889 } 889 }
890 }; 890 };
891 891
892 $state{handle}->push_read (line => $qr_nlnl, $state{read_response}); 892 $state{handle}->push_read (line => $qr_nlnl, $state{read_response});

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines