| Filename | /usr/share/perl5/LWP/Protocol.pm |
| Statements | Executed 20 statements in 1.18ms |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 1 | 1 | 1 | 19µs | 26µs | LWP::Protocol::BEGIN@7 |
| 1 | 1 | 1 | 14µs | 14µs | LWP::Protocol::BEGIN@10 |
| 1 | 1 | 1 | 11µs | 32µs | LWP::Protocol::BEGIN@62 |
| 1 | 1 | 1 | 6µs | 6µs | LWP::Protocol::BEGIN@8 |
| 1 | 1 | 1 | 5µs | 5µs | LWP::Protocol::BEGIN@9 |
| 0 | 0 | 0 | 0s | 0s | LWP::Protocol::__ANON__[:111] |
| 0 | 0 | 0 | 0s | 0s | LWP::Protocol::__ANON__[:117] |
| 0 | 0 | 0 | 0s | 0s | LWP::Protocol::__ANON__[:125] |
| 0 | 0 | 0 | 0s | 0s | LWP::Protocol::__ANON__[:139] |
| 0 | 0 | 0 | 0s | 0s | LWP::Protocol::__ANON__[:186] |
| 0 | 0 | 0 | 0s | 0s | LWP::Protocol::collect |
| 0 | 0 | 0 | 0s | 0s | LWP::Protocol::collect_once |
| 0 | 0 | 0 | 0s | 0s | LWP::Protocol::create |
| 0 | 0 | 0 | 0s | 0s | LWP::Protocol::implementor |
| 0 | 0 | 0 | 0s | 0s | LWP::Protocol::max_size |
| 0 | 0 | 0 | 0s | 0s | LWP::Protocol::new |
| 0 | 0 | 0 | 0s | 0s | LWP::Protocol::request |
| 0 | 0 | 0 | 0s | 0s | LWP::Protocol::timeout |
| Line | State ments |
Time on line |
Calls | Time in subs |
Code |
|---|---|---|---|---|---|
| 1 | package LWP::Protocol; | ||||
| 2 | |||||
| 3 | 1 | 121µs | require LWP::MemberMixin; | ||
| 4 | 1 | 10µs | @ISA = qw(LWP::MemberMixin); | ||
| 5 | 1 | 500ns | $VERSION = "5.829"; | ||
| 6 | |||||
| 7 | 3 | 31µs | 2 | 33µs | # spent 26µs (19+7) within LWP::Protocol::BEGIN@7 which was called:
# once (19µs+7µs) by LWP::UserAgent::BEGIN@15 at line 7 # spent 26µs making 1 call to LWP::Protocol::BEGIN@7
# spent 7µs making 1 call to strict::import |
| 8 | 3 | 21µs | 1 | 6µs | # spent 6µs within LWP::Protocol::BEGIN@8 which was called:
# once (6µs+0s) by LWP::UserAgent::BEGIN@15 at line 8 # spent 6µs making 1 call to LWP::Protocol::BEGIN@8 |
| 9 | 3 | 22µs | 1 | 5µs | # spent 5µs within LWP::Protocol::BEGIN@9 which was called:
# once (5µs+0s) by LWP::UserAgent::BEGIN@15 at line 9 # spent 5µs making 1 call to LWP::Protocol::BEGIN@9 |
| 10 | 3 | 258µs | 1 | 14µs | # spent 14µs within LWP::Protocol::BEGIN@10 which was called:
# once (14µs+0s) by LWP::UserAgent::BEGIN@15 at line 10 # spent 14µs making 1 call to LWP::Protocol::BEGIN@10 |
| 11 | |||||
| 12 | 1 | 700ns | my %ImplementedBy = (); # scheme => classname | ||
| 13 | |||||
| - - | |||||
| 16 | sub new | ||||
| 17 | { | ||||
| 18 | my($class, $scheme, $ua) = @_; | ||||
| 19 | |||||
| 20 | my $self = bless { | ||||
| 21 | scheme => $scheme, | ||||
| 22 | ua => $ua, | ||||
| 23 | |||||
| 24 | # historical/redundant | ||||
| 25 | max_size => $ua->{max_size}, | ||||
| 26 | }, $class; | ||||
| 27 | |||||
| 28 | $self; | ||||
| 29 | } | ||||
| 30 | |||||
| 31 | |||||
| 32 | sub create | ||||
| 33 | { | ||||
| 34 | my($scheme, $ua) = @_; | ||||
| 35 | my $impclass = LWP::Protocol::implementor($scheme) or | ||||
| 36 | Carp::croak("Protocol scheme '$scheme' is not supported"); | ||||
| 37 | |||||
| 38 | # hand-off to scheme specific implementation sub-class | ||||
| 39 | my $protocol = $impclass->new($scheme, $ua); | ||||
| 40 | |||||
| 41 | return $protocol; | ||||
| 42 | } | ||||
| 43 | |||||
| 44 | |||||
| 45 | sub implementor | ||||
| 46 | { | ||||
| 47 | my($scheme, $impclass) = @_; | ||||
| 48 | |||||
| 49 | if ($impclass) { | ||||
| 50 | $ImplementedBy{$scheme} = $impclass; | ||||
| 51 | } | ||||
| 52 | my $ic = $ImplementedBy{$scheme}; | ||||
| 53 | return $ic if $ic; | ||||
| 54 | |||||
| 55 | return '' unless $scheme =~ /^([.+\-\w]+)$/; # check valid URL schemes | ||||
| 56 | $scheme = $1; # untaint | ||||
| 57 | $scheme =~ s/[.+\-]/_/g; # make it a legal module name | ||||
| 58 | |||||
| 59 | # scheme not yet known, look for a 'use'd implementation | ||||
| 60 | $ic = "LWP::Protocol::$scheme"; # default location | ||||
| 61 | $ic = "LWP::Protocol::nntp" if $scheme eq 'news'; #XXX ugly hack | ||||
| 62 | 3 | 714µs | 2 | 54µs | # spent 32µs (11+21) within LWP::Protocol::BEGIN@62 which was called:
# once (11µs+21µs) by LWP::UserAgent::BEGIN@15 at line 62 # spent 32µs making 1 call to LWP::Protocol::BEGIN@62
# spent 21µs making 1 call to strict::unimport |
| 63 | # check we actually have one for the scheme: | ||||
| 64 | unless (@{"${ic}::ISA"}) { | ||||
| 65 | # try to autoload it | ||||
| 66 | eval "require $ic"; | ||||
| 67 | if ($@) { | ||||
| 68 | if ($@ =~ /Can't locate/) { #' #emacs get confused by ' | ||||
| 69 | $ic = ''; | ||||
| 70 | } | ||||
| 71 | else { | ||||
| 72 | die "$@\n"; | ||||
| 73 | } | ||||
| 74 | } | ||||
| 75 | } | ||||
| 76 | $ImplementedBy{$scheme} = $ic if $ic; | ||||
| 77 | $ic; | ||||
| 78 | } | ||||
| 79 | |||||
| 80 | |||||
| 81 | sub request | ||||
| 82 | { | ||||
| 83 | my($self, $request, $proxy, $arg, $size, $timeout) = @_; | ||||
| 84 | Carp::croak('LWP::Protocol::request() needs to be overridden in subclasses'); | ||||
| 85 | } | ||||
| 86 | |||||
| 87 | |||||
| 88 | # legacy | ||||
| 89 | sub timeout { shift->_elem('timeout', @_); } | ||||
| 90 | sub max_size { shift->_elem('max_size', @_); } | ||||
| 91 | |||||
| 92 | |||||
| 93 | sub collect | ||||
| 94 | { | ||||
| 95 | my ($self, $arg, $response, $collector) = @_; | ||||
| 96 | my $content; | ||||
| 97 | my($ua, $max_size) = @{$self}{qw(ua max_size)}; | ||||
| 98 | |||||
| 99 | eval { | ||||
| 100 | local $\; # protect the print below from surprises | ||||
| 101 | if (!defined($arg) || !$response->is_success) { | ||||
| 102 | $response->{default_add_content} = 1; | ||||
| 103 | } | ||||
| 104 | elsif (!ref($arg) && length($arg)) { | ||||
| 105 | open(my $fh, ">", $arg) or die "Can't write to '$arg': $!"; | ||||
| 106 | binmode($fh); | ||||
| 107 | push(@{$response->{handlers}{response_data}}, { | ||||
| 108 | callback => sub { | ||||
| 109 | print $fh $_[3] or die "Can't write to '$arg': $!"; | ||||
| 110 | 1; | ||||
| 111 | }, | ||||
| 112 | }); | ||||
| 113 | push(@{$response->{handlers}{response_done}}, { | ||||
| 114 | callback => sub { | ||||
| 115 | close($fh) or die "Can't write to '$arg': $!"; | ||||
| 116 | undef($fh); | ||||
| 117 | }, | ||||
| 118 | }); | ||||
| 119 | } | ||||
| 120 | elsif (ref($arg) eq 'CODE') { | ||||
| 121 | push(@{$response->{handlers}{response_data}}, { | ||||
| 122 | callback => sub { | ||||
| 123 | &$arg($_[3], $_[0], $self); | ||||
| 124 | 1; | ||||
| 125 | }, | ||||
| 126 | }); | ||||
| 127 | } | ||||
| 128 | else { | ||||
| 129 | die "Unexpected collect argument '$arg'"; | ||||
| 130 | } | ||||
| 131 | |||||
| 132 | $ua->run_handlers("response_header", $response); | ||||
| 133 | |||||
| 134 | if (delete $response->{default_add_content}) { | ||||
| 135 | push(@{$response->{handlers}{response_data}}, { | ||||
| 136 | callback => sub { | ||||
| 137 | $_[0]->add_content($_[3]); | ||||
| 138 | 1; | ||||
| 139 | }, | ||||
| 140 | }); | ||||
| 141 | } | ||||
| 142 | |||||
| 143 | |||||
| 144 | my $content_size = 0; | ||||
| 145 | my $length = $response->content_length; | ||||
| 146 | my %skip_h; | ||||
| 147 | |||||
| 148 | while ($content = &$collector, length $$content) { | ||||
| 149 | for my $h ($ua->handlers("response_data", $response)) { | ||||
| 150 | next if $skip_h{$h}; | ||||
| 151 | unless ($h->{callback}->($response, $ua, $h, $$content)) { | ||||
| 152 | # XXX remove from $response->{handlers}{response_data} if present | ||||
| 153 | $skip_h{$h}++; | ||||
| 154 | } | ||||
| 155 | } | ||||
| 156 | $content_size += length($$content); | ||||
| 157 | $ua->progress(($length ? ($content_size / $length) : "tick"), $response); | ||||
| 158 | if (defined($max_size) && $content_size > $max_size) { | ||||
| 159 | $response->push_header("Client-Aborted", "max_size"); | ||||
| 160 | last; | ||||
| 161 | } | ||||
| 162 | } | ||||
| 163 | }; | ||||
| 164 | my $err = $@; | ||||
| 165 | delete $response->{handlers}{response_data}; | ||||
| 166 | delete $response->{handlers} unless %{$response->{handlers}}; | ||||
| 167 | if ($err) { | ||||
| 168 | chomp($err); | ||||
| 169 | $response->push_header('X-Died' => $err); | ||||
| 170 | $response->push_header("Client-Aborted", "die"); | ||||
| 171 | return $response; | ||||
| 172 | } | ||||
| 173 | |||||
| 174 | return $response; | ||||
| 175 | } | ||||
| 176 | |||||
| 177 | |||||
| 178 | sub collect_once | ||||
| 179 | { | ||||
| 180 | my($self, $arg, $response) = @_; | ||||
| 181 | my $content = \ $_[3]; | ||||
| 182 | my $first = 1; | ||||
| 183 | $self->collect($arg, $response, sub { | ||||
| 184 | return $content if $first--; | ||||
| 185 | return \ ""; | ||||
| 186 | }); | ||||
| 187 | } | ||||
| 188 | |||||
| 189 | 1 | 5µs | 1; | ||
| 190 | |||||
| 191 | |||||
| 192 | __END__ |