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.82 by root, Sun Jan 2 04:50:40 2011 UTC vs.
Revision 1.88 by root, Sun Jan 2 20:57:03 2011 UTC

36 36
37=cut 37=cut
38 38
39package AnyEvent::HTTP; 39package AnyEvent::HTTP;
40 40
41use strict; 41use common::sense;
42no warnings;
43 42
44use Errno (); 43use Errno ();
45 44
46use AnyEvent 5.0 (); 45use AnyEvent 5.0 ();
47use AnyEvent::Util (); 46use AnyEvent::Util ();
58our $MAX_PERSISTENT = 8; 57our $MAX_PERSISTENT = 8;
59our $PERSISTENT_TIMEOUT = 2; 58our $PERSISTENT_TIMEOUT = 2;
60our $TIMEOUT = 300; 59our $TIMEOUT = 300;
61 60
62# changing these is evil 61# changing these is evil
63our $MAX_PERSISTENT_PER_HOST = 0; 62our $MAX_PERSISTENT_PER_HOST = 2;
64our $MAX_PER_HOST = 4; 63our $MAX_PER_HOST = 4;
65 64
66our $PROXY; 65our $PROXY;
67our $ACTIVE = 0; 66our $ACTIVE = 0;
68 67
530 $cdom = $uhost; 529 $cdom = $uhost;
531 } 530 }
532 531
533 # store it 532 # store it
534 $jar->{version} = 1; 533 $jar->{version} = 1;
535 $jar->{$cdom}{$cpath}{$name} = \%kv; 534 $jar->{lc $cdom}{$cpath}{$name} = \%kv;
536 535
537 redo if /\G\s*,/gc; 536 redo if /\G\s*,/gc;
538 } 537 }
539} 538}
540 539
607 : return $cb->(undef, { @pseudo, Status => 599, Reason => "Only http and https URL schemes supported" }); 606 : return $cb->(undef, { @pseudo, Status => 599, Reason => "Only http and https URL schemes supported" });
608 607
609 $uauthority =~ /^(?: .*\@ )? ([^\@:]+) (?: : (\d+) )?$/x 608 $uauthority =~ /^(?: .*\@ )? ([^\@:]+) (?: : (\d+) )?$/x
610 or return $cb->(undef, { @pseudo, Status => 599, Reason => "Unparsable URL" }); 609 or return $cb->(undef, { @pseudo, Status => 599, Reason => "Unparsable URL" });
611 610
612 my $uhost = $1; 611 my $uhost = lc $1;
613 $uport = $2 if defined $2; 612 $uport = $2 if defined $2;
614 613
615 $hdr{host} = defined $2 ? "$uhost:$2" : "$uhost" 614 $hdr{host} = defined $2 ? "$uhost:$2" : "$uhost"
616 unless exists $hdr{host}; 615 unless exists $hdr{host};
617 616
636 $rscheme = "http" unless defined $rscheme; 635 $rscheme = "http" unless defined $rscheme;
637 636
638 # don't support https requests over https-proxy transport, 637 # don't support https requests over https-proxy transport,
639 # can't be done with tls as spec'ed, unless you double-encrypt. 638 # can't be done with tls as spec'ed, unless you double-encrypt.
640 $rscheme = "http" if $uscheme eq "https" && $rscheme eq "https"; 639 $rscheme = "http" if $uscheme eq "https" && $rscheme eq "https";
640
641 $rhost = lc $rhost;
642 $rscheme = lc $rscheme;
641 } else { 643 } else {
642 ($rhost, $rport, $rscheme, $rpath) = ($uhost, $uport, $uscheme, $upath); 644 ($rhost, $rport, $rscheme, $rpath) = ($uhost, $uport, $uscheme, $upath);
643 } 645 }
644 646
645 # leave out fragment and query string, just a heuristic 647 # leave out fragment and query string, just a heuristic
647 $hdr{"user-agent"} = $USERAGENT unless exists $hdr{"user-agent"}; 649 $hdr{"user-agent"} = $USERAGENT unless exists $hdr{"user-agent"};
648 650
649 $hdr{"content-length"} = length $arg{body} 651 $hdr{"content-length"} = length $arg{body}
650 if length $arg{body} || $method ne "GET"; 652 if length $arg{body} || $method ne "GET";
651 653
652 $hdr{connection} = "close TE"; #1.1 654 $hdr{connection} = "close Te"; #1.1
653 $hdr{te} = "trailers" unless exists $hdr{te}; #1.1 655 $hdr{te} = "trailers" unless exists $hdr{te}; #1.1
654 656
655 my %state = (connect_guard => 1); 657 my %state = (connect_guard => 1);
656 658
657 _get_slot $uhost, sub {
658 $state{slot_guard} = shift;
659
660 return unless $state{connect_guard};
661
662 my $ae_error = 595; # connecting 659 my $ae_error = 595; # connecting
663 660
664 # handle actual, non-tunneled, request 661 # handle actual, non-tunneled, request
665 my $handle_actual_request = sub { 662 my $handle_actual_request = sub {
666 $ae_error = 596; # request phase 663 $ae_error = 596; # request phase
667 664
668 $state{handle}->starttls ("connect") if $uscheme eq "https" && !exists $state{handle}{tls}; 665 $state{handle}->starttls ("connect") if $uscheme eq "https" && !exists $state{handle}{tls};
669 666
670 # send request 667 # send request
671 $state{handle}->push_write ( 668 $state{handle}->push_write (
672 "$method $rpath HTTP/1.1\015\012" 669 "$method $rpath HTTP/1.1\015\012"
673 . (join "", map "\u$_: $hdr{$_}\015\012", grep defined $hdr{$_}, keys %hdr) 670 . (join "", map "\u$_: $hdr{$_}\015\012", grep defined $hdr{$_}, keys %hdr)
674 . "\015\012" 671 . "\015\012"
675 . (delete $arg{body}) 672 . (delete $arg{body})
676 ); 673 );
677 674
678 # return if error occured during push_write() 675 # return if error occured during push_write()
679 return unless %state; 676 return unless %state;
680 677
681 %hdr = (); # reduce memory usage, save a kitten, also make it possible to re-use 678 %hdr = (); # reduce memory usage, save a kitten, also make it possible to re-use
682 679
683 # status line and headers 680 # status line and headers
684 $state{read_response} = sub { 681 $state{read_response} = sub {
685 for ("$_[1]") { 682 for ("$_[1]") {
686 y/\015//d; # weed out any \015, as they show up in the weirdest of places. 683 y/\015//d; # weed out any \015, as they show up in the weirdest of places.
687 684
688 /^HTTP\/0*([0-9\.]+) \s+ ([0-9]{3}) (?: \s+ ([^\012]*) )? \012/gxci 685 /^HTTP\/0*([0-9\.]+) \s+ ([0-9]{3}) (?: \s+ ([^\012]*) )? \012/gxci
689 or return (%state = (), $cb->(undef, { @pseudo, Status => 599, Reason => "Invalid server response" })); 686 or return (%state = (), $cb->(undef, { @pseudo, Status => 599, Reason => "Invalid server response" }));
690 687
691 # 100 Continue handling 688 # 100 Continue handling
692 # should not happen as we don't send expect: 100-continue, 689 # should not happen as we don't send expect: 100-continue,
693 # but we handle it just in case. 690 # but we handle it just in case.
694 # since we send the request body regardless, if we get an error 691 # since we send the request body regardless, if we get an error
695 # we are out of-sync, which we currently do NOT handle correctly. 692 # we are out of-sync, which we currently do NOT handle correctly.
696 return $state{handle}->push_read (line => $qr_nlnl, $state{read_response}) 693 return $state{handle}->push_read (line => $qr_nlnl, $state{read_response})
697 if $2 eq 100; 694 if $2 eq 100;
698 695
699 push @pseudo, 696 push @pseudo,
700 HTTPVersion => $1, 697 HTTPVersion => $1,
701 Status => $2, 698 Status => $2,
702 Reason => $3, 699 Reason => $3,
703 ; 700 ;
704 701
705 my $hdr = parse_hdr 702 my $hdr = parse_hdr
706 or return (%state = (), $cb->(undef, { @pseudo, Status => 599, Reason => "Garbled response headers" })); 703 or return (%state = (), $cb->(undef, { @pseudo, Status => 599, Reason => "Garbled response headers" }));
707 704
708 %hdr = (%$hdr, @pseudo); 705 %hdr = (%$hdr, @pseudo);
706 }
707
708 # redirect handling
709 # microsoft and other shitheads don't give a shit for following standards,
710 # try to support some common forms of broken Location headers.
711 if ($hdr{location} !~ /^(?: $ | [^:\/?\#]+ : )/x) {
712 $hdr{location} =~ s/^\.\/+//;
713
714 my $url = "$rscheme://$uhost:$uport";
715
716 unless ($hdr{location} =~ s/^\///) {
717 $url .= $upath;
718 $url =~ s/\/[^\/]*$//;
709 } 719 }
710 720
711 # redirect handling
712 # microsoft and other shitheads don't give a shit for following standards,
713 # try to support some common forms of broken Location headers.
714 if ($hdr{location} !~ /^(?: $ | [^:\/?\#]+ : )/x) {
715 $hdr{location} =~ s/^\.\/+//;
716
717 my $url = "$rscheme://$uhost:$uport";
718
719 unless ($hdr{location} =~ s/^\///) {
720 $url .= $upath;
721 $url =~ s/\/[^\/]*$//;
722 }
723
724 $hdr{location} = "$url/$hdr{location}"; 721 $hdr{location} = "$url/$hdr{location}";
722 }
723
724 my $redirect;
725
726 if ($recurse) {
727 my $status = $hdr{Status};
728
729 # industry standard is to redirect POST as GET for
730 # 301, 302 and 303, in contrast to HTTP/1.0 and 1.1.
731 # also, the UA should ask the user for 301 and 307 and POST,
732 # industry standard seems to be to simply follow.
733 # we go with the industry standard.
734 if ($status == 301 or $status == 302 or $status == 303) {
735 # HTTP/1.1 is unclear on how to mutate the method
736 $method = "GET" unless $method eq "HEAD";
737 $redirect = 1;
738 } elsif ($status == 307) {
739 $redirect = 1;
725 } 740 }
726
727 my $redirect;
728
729 if ($recurse) {
730 my $status = $hdr{Status};
731
732 # industry standard is to redirect POST as GET for
733 # 301, 302 and 303, in contrast to HTTP/1.0 and 1.1.
734 # also, the UA should ask the user for 301 and 307 and POST,
735 # industry standard seems to be to simply follow.
736 # we go with the industry standard.
737 if ($status == 301 or $status == 302 or $status == 303) {
738 # HTTP/1.1 is unclear on how to mutate the method
739 $method = "GET" unless $method eq "HEAD";
740 $redirect = 1;
741 } elsif ($status == 307) {
742 $redirect = 1;
743 } 741 }
742
743 my $finish = sub { # ($data, $err_status, $err_reason[, $keepalive])
744 my $may_keep_alive = $_[3];
745
746 $state{handle}->destroy if $state{handle};
747 %state = ();
748
749 if (defined $_[1]) {
750 $hdr{OrigStatus} = $hdr{Status}; $hdr{Status} = $_[1];
751 $hdr{OrigReason} = $hdr{Reason}; $hdr{Reason} = $_[2];
744 } 752 }
745 753
746 my $finish = sub { # ($data, $err_status, $err_reason[, $keepalive])
747 my $may_keep_alive = $_[3];
748
749 $state{handle}->destroy if $state{handle};
750 %state = ();
751
752 if (defined $_[1]) {
753 $hdr{OrigStatus} = $hdr{Status}; $hdr{Status} = $_[1];
754 $hdr{OrigReason} = $hdr{Reason}; $hdr{Reason} = $_[2];
755 }
756
757 # set-cookie processing 754 # set-cookie processing
758 if ($arg{cookie_jar}) { 755 if ($arg{cookie_jar}) {
759 cookie_jar_set_cookie $arg{cookie_jar}, $hdr{"set-cookie"}, $uhost, $hdr{date}; 756 cookie_jar_set_cookie $arg{cookie_jar}, $hdr{"set-cookie"}, $uhost, $hdr{date};
760 } 757 }
761 758
762 if ($redirect && exists $hdr{location}) { 759 if ($redirect && exists $hdr{location}) {
763 # we ignore any errors, as it is very common to receive 760 # we ignore any errors, as it is very common to receive
764 # Content-Length != 0 but no actual body 761 # Content-Length != 0 but no actual body
765 # we also access %hdr, as $_[1] might be an erro 762 # we also access %hdr, as $_[1] might be an erro
766 http_request ( 763 http_request (
767 $method => $hdr{location}, 764 $method => $hdr{location},
768 %arg, 765 %arg,
769 recurse => $recurse - 1, 766 recurse => $recurse - 1,
770 Redirect => [$_[0], \%hdr], 767 Redirect => [$_[0], \%hdr],
771 $cb); 768 $cb);
769 } else {
770 $cb->($_[0], \%hdr);
771 }
772 };
773
774 $ae_error = 597; # body phase
775
776 my $len = $hdr{"content-length"};
777
778 # body handling, many different code paths
779 # - no body expected
780 # - want_body_handle
781 # - te chunked
782 # - 2x length known (with or without on_body)
783 # - 2x length not known (with or without on_body)
784 if (!$redirect && $arg{on_header} && !$arg{on_header}(\%hdr)) {
785 $finish->(undef, 598 => "Request cancelled by on_header");
786 } elsif (
787 $hdr{Status} =~ /^(?:1..|204|205|304)$/
788 or $method eq "HEAD"
789 or (defined $len && $len == 0) # == 0, not !, because "0 " is true
790 ) {
791 # no body
792 $finish->("", undef, undef, 1);
793
794 } elsif (!$redirect && $arg{want_body_handle}) {
795 $_[0]->on_eof (undef);
796 $_[0]->on_error (undef);
797 $_[0]->on_read (undef);
798
799 $finish->(delete $state{handle});
800
801 } elsif ($hdr{"transfer-encoding"} =~ /\bchunked\b/i) {
802 my $cl = 0;
803 my $body = undef;
804 my $on_body = $arg{on_body} || sub { $body .= shift; 1 };
805
806 $state{read_chunk} = sub {
807 $_[1] =~ /^([0-9a-fA-F]+)/
808 or $finish->(undef, $ae_error => "Garbled chunked transfer encoding");
809
810 my $len = hex $1;
811
812 if ($len) {
813 $cl += $len;
814
815 $_[0]->push_read (chunk => $len, sub {
816 $on_body->($_[1], \%hdr)
817 or return $finish->(undef, 598 => "Request cancelled by on_body");
818
819 $_[0]->push_read (line => sub {
820 length $_[1]
821 and return $finish->(undef, $ae_error => "Garbled chunked transfer encoding");
822 $_[0]->push_read (line => $state{read_chunk});
823 });
824 });
772 } else { 825 } else {
773 $cb->($_[0], \%hdr); 826 $hdr{"content-length"} ||= $cl;
827
828 $_[0]->push_read (line => $qr_nlnl, sub {
829 if (length $_[1]) {
830 for ("$_[1]") {
831 y/\015//d; # weed out any \015, as they show up in the weirdest of places.
832
833 my $hdr = parse_hdr
834 or return $finish->(undef, $ae_error => "Garbled response trailers");
835
836 %hdr = (%hdr, %$hdr);
837 }
838 }
839
840 $finish->($body, undef, undef, 1);
841 });
774 } 842 }
775 }; 843 };
776 844
777 $ae_error = 597; # body phase 845 $_[0]->push_read (line => $state{read_chunk});
778 846
779 my $len = $hdr{"content-length"}; 847 } elsif ($arg{on_body}) {
848 if (defined $len) {
849 $_[0]->on_read (sub {
850 $len -= length $_[0]{rbuf};
780 851
781 if (!$redirect && $arg{on_header} && !$arg{on_header}(\%hdr)) { 852 $arg{on_body}(delete $_[0]{rbuf}, \%hdr)
782 $finish->(undef, 598 => "Request cancelled by on_header"); 853 or return $finish->(undef, 598 => "Request cancelled by on_body");
783 } elsif ( 854
784 $hdr{Status} =~ /^(?:1..|204|205|304)$/ 855 $len > 0
785 or $method eq "HEAD"
786 or (defined $len && !$len)
787 ) {
788 # no body
789 $finish->("", undef, undef, 1); 856 or $finish->("", undef, undef, 1);
857 });
790 } else { 858 } else {
791 # body handling, many different code paths
792 # - no body expected
793 # - want_body_handle
794 # - te chunked
795 # - 2x length known (with or without on_body)
796 # - 2x length not known (with or without on_body)
797 if (!$redirect && $arg{want_body_handle}) {
798 $_[0]->on_eof (undef); 859 $_[0]->on_eof (sub {
799 $_[0]->on_error (undef); 860 $finish->("");
800 $_[0]->on_read (undef);
801
802 $finish->(delete $state{handle});
803
804 } elsif ($hdr{"transfer-encoding"} =~ /\bchunked\b/i) {
805 my $cl = 0;
806 my $body = undef;
807 my $on_body = $arg{on_body} || sub { $body .= shift; 1 };
808
809 $state{read_chunk} = sub {
810 $_[1] =~ /^([0-9a-fA-F]+)/
811 or $finish->(undef, $ae_error => "Garbled chunked transfer encoding");
812
813 my $len = hex $1;
814
815 if ($len) {
816 $cl += $len;
817
818 $_[0]->push_read (chunk => $len, sub {
819 $on_body->($_[1], \%hdr)
820 or return $finish->(undef, 598 => "Request cancelled by on_body");
821
822 $_[0]->push_read (line => sub {
823 length $_[1]
824 and return $finish->(undef, $ae_error => "Garbled chunked transfer encoding");
825 $_[0]->push_read (line => $state{read_chunk});
826 });
827 });
828 } else {
829 $hdr{"content-length"} ||= $cl;
830
831 $_[0]->push_read (line => $qr_nlnl, sub {
832 if (length $_[1]) {
833 for ("$_[1]") {
834 y/\015//d; # weed out any \015, as they show up in the weirdest of places.
835
836 my $hdr = parse_hdr
837 or return $finish->(undef, $ae_error => "Garbled response trailers");
838
839 %hdr = (%hdr, %$hdr);
840 }
841 }
842
843 $finish->($body, undef, undef, 1);
844 });
845 }
846 }; 861 });
847
848 $_[0]->push_read (line => $state{read_chunk});
849
850 } elsif ($arg{on_body}) {
851 if ($len) {
852 $_[0]->on_read (sub { 862 $_[0]->on_read (sub {
853 $len -= length $_[0]{rbuf};
854
855 $arg{on_body}(delete $_[0]{rbuf}, \%hdr) 863 $arg{on_body}(delete $_[0]{rbuf}, \%hdr)
856 or return $finish->(undef, 598 => "Request cancelled by on_body");
857
858 $len > 0
859 or $finish->("", undef, undef, 1);
860 });
861 } else {
862 $_[0]->on_eof (sub {
863 $finish->("");
864 });
865 $_[0]->on_read (sub {
866 $arg{on_body}(delete $_[0]{rbuf}, \%hdr)
867 or $finish->(undef, 598 => "Request cancelled by on_body"); 864 or $finish->(undef, 598 => "Request cancelled by on_body");
868 });
869 }
870 } else {
871 $_[0]->on_eof (undef);
872
873 if ($len) {
874 $_[0]->on_read (sub {
875 $finish->((substr delete $_[0]{rbuf}, 0, $len, ""), undef, undef, 1)
876 if $len <= length $_[0]{rbuf};
877 });
878 } else {
879 $_[0]->on_error (sub {
880 ($! == Errno::EPIPE || !$!)
881 ? $finish->(delete $_[0]{rbuf})
882 : $finish->(undef, $ae_error => $_[2]);
883 });
884 $_[0]->on_read (sub { });
885 }
886 } 865 });
887 } 866 }
867 } else {
868 $_[0]->on_eof (undef);
869
870 if (defined $len) {
871 $_[0]->on_read (sub {
872 $finish->((substr delete $_[0]{rbuf}, 0, $len, ""), undef, undef, 1)
873 if $len <= length $_[0]{rbuf};
874 });
875 } else {
876 $_[0]->on_error (sub {
877 ($! == Errno::EPIPE || !$!)
878 ? $finish->(delete $_[0]{rbuf})
879 : $finish->(undef, $ae_error => $_[2]);
880 });
881 $_[0]->on_read (sub { });
882 }
883 }
884 };
885
886 $state{handle}->push_read (line => $qr_nlnl, $state{read_response});
887 };
888
889 my $connect_cb = sub {
890 $state{fh} = shift
891 or do {
892 my $err = "$!";
893 %state = ();
894 return $cb->(undef, { @pseudo, Status => $ae_error, Reason => $err });
888 }; 895 };
889 896
890 $state{handle}->push_read (line => $qr_nlnl, $state{read_response});
891 };
892
893 my $connect_cb = sub {
894 $state{fh} = shift
895 or do {
896 my $err = "$!";
897 %state = ();
898 return $cb->(undef, { @pseudo, Status => $ae_error, Reason => $err });
899 };
900
901 return unless delete $state{connect_guard}; 897 return unless delete $state{connect_guard};
902 898
903 # get handle 899 # get handle
904 $state{handle} = new AnyEvent::Handle 900 $state{handle} = new AnyEvent::Handle
905 fh => $state{fh}, 901 fh => $state{fh},
906 peername => $rhost, 902 peername => $rhost,
907 tls_ctx => $arg{tls_ctx}, 903 tls_ctx => $arg{tls_ctx},
908 # these need to be reconfigured on keepalive handles 904 # these need to be reconfigured on keepalive handles
909 timeout => $timeout, 905 timeout => $timeout,
910 on_error => sub { 906 on_error => sub {
911 %state = (); 907 %state = ();
912 $cb->(undef, { @pseudo, Status => $ae_error, Reason => $_[2] }); 908 $cb->(undef, { @pseudo, Status => $ae_error, Reason => $_[2] });
913 }, 909 },
914 on_eof => sub { 910 on_eof => sub {
915 %state = (); 911 %state = ();
916 $cb->(undef, { @pseudo, Status => $ae_error, Reason => "Unexpected end-of-file" }); 912 $cb->(undef, { @pseudo, Status => $ae_error, Reason => "Unexpected end-of-file" });
917 }, 913 },
918 ; 914 ;
919 915
920 # limit the number of persistent connections 916 # limit the number of persistent connections
921 # keepalive not yet supported 917 # keepalive not yet supported
922# if ($KA_COUNT{$_[1]} < $MAX_PERSISTENT_PER_HOST) { 918# if ($KA_COUNT{$_[1]} < $MAX_PERSISTENT_PER_HOST) {
923# ++$KA_COUNT{$_[1]}; 919# ++$KA_COUNT{$_[1]};
924# $state{handle}{ka_count_guard} = AnyEvent::Util::guard { 920# $state{handle}{ka_count_guard} = AnyEvent::Util::guard {
925# --$KA_COUNT{$_[1]} 921# --$KA_COUNT{$_[1]}
926# }; 922# };
927# $hdr{connection} = "keep-alive"; 923# $hdr{connection} = "keep-alive";
928# } 924# }
929 925
930 $state{handle}->starttls ("connect") if $rscheme eq "https"; 926 $state{handle}->starttls ("connect") if $rscheme eq "https";
931 927
932 # now handle proxy-CONNECT method 928 # now handle proxy-CONNECT method
933 if ($proxy && $uscheme eq "https") { 929 if ($proxy && $uscheme eq "https") {
934 # oh dear, we have to wrap it into a connect request 930 # oh dear, we have to wrap it into a connect request
935 931
936 # maybe re-use $uauthority with patched port? 932 # maybe re-use $uauthority with patched port?
937 $state{handle}->push_write ("CONNECT $uhost:$uport HTTP/1.0\015\012Host: $uhost\015\012\015\012"); 933 $state{handle}->push_write ("CONNECT $uhost:$uport HTTP/1.0\015\012\015\012");
938 $state{handle}->push_read (line => $qr_nlnl, sub { 934 $state{handle}->push_read (line => $qr_nlnl, sub {
939 $_[1] =~ /^HTTP\/([0-9\.]+) \s+ ([0-9]{3}) (?: \s+ ([^\015\012]*) )?/ix 935 $_[1] =~ /^HTTP\/([0-9\.]+) \s+ ([0-9]{3}) (?: \s+ ([^\015\012]*) )?/ix
940 or return (%state = (), $cb->(undef, { @pseudo, Status => 599, Reason => "Invalid proxy connect response ($_[1])" })); 936 or return (%state = (), $cb->(undef, { @pseudo, Status => 599, Reason => "Invalid proxy connect response ($_[1])" }));
941 937
942 if ($2 == 200) { 938 if ($2 == 200) {
943 $rpath = $upath; 939 $rpath = $upath;
944 $handle_actual_request->(); 940 $handle_actual_request->();
945 } else { 941 } else {
946 %state = (); 942 %state = ();
947 $cb->(undef, { @pseudo, Status => $2, Reason => $3 }); 943 $cb->(undef, { @pseudo, Status => $2, Reason => $3 });
948 }
949 }); 944 }
945 });
950 } else { 946 } else {
951 $handle_actual_request->(); 947 $handle_actual_request->();
952 }
953 }; 948 }
949 };
950
951 _get_slot $uhost, sub {
952 $state{slot_guard} = shift;
953
954 return unless $state{connect_guard};
954 955
955 my $tcp_connect = $arg{tcp_connect} 956 my $tcp_connect = $arg{tcp_connect}
956 || do { require AnyEvent::Socket; \&AnyEvent::Socket::tcp_connect }; 957 || do { require AnyEvent::Socket; \&AnyEvent::Socket::tcp_connect };
957 958
958 $state{connect_guard} = $tcp_connect->($rhost, $rport, $connect_cb, $arg{on_prepare} || sub { $timeout }); 959 $state{connect_guard} = $tcp_connect->($rhost, $rport, $connect_cb, $arg{on_prepare} || sub { $timeout });

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines