| blib/lib/POE/Component/Server/SimpleContent.pm | |||
|---|---|---|---|
| Criterion | Covered | Total | % |
| statement | 177 | 228 | 77.6 |
| branch | 50 | 92 | 54.3 |
| condition | 21 | 54 | 38.8 |
| subroutine | 29 | 33 | 87.8 |
| pod | 11 | 12 | 91.6 |
| total | 288 | 419 | 68.7 |
| line | stmt | bran | cond | sub | pod | time | code |
|---|---|---|---|---|---|---|---|
| 1 | package POE::Component::Server::SimpleContent; | ||||||
| 2 | $POE::Component::Server::SimpleContent::VERSION = '1.16'; | ||||||
| 3 | #ABSTRACT: The easy way to serve web content with POE::Component::Server::SimpleHTTP. | ||||||
| 4 | |||||||
| 5 | # We export some stuff | ||||||
| 6 | require Exporter; | ||||||
| 7 | @ISA = qw( Exporter ); | ||||||
| 8 | @EXPORT = qw(generate_301 generate_404 generate_403); | ||||||
| 9 | |||||||
| 10 | 7 | 7 | 114167 | use strict; | |||
| 7 | 14 | ||||||
| 7 | 212 | ||||||
| 11 | 7 | 7 | 55 | use warnings; | |||
| 7 | 11 | ||||||
| 7 | 197 | ||||||
| 12 | 7 | 7 | 26 | use Carp; | |||
| 7 | 8 | ||||||
| 7 | 603 | ||||||
| 13 | 7 | 7 | 3594 | use POE qw( Wheel::ReadWrite Filter::Stream ); | |||
| 7 | 272593 | ||||||
| 7 | 48 | ||||||
| 14 | 7 | 7 | 389865 | use CGI qw(:standard); | |||
| 7 | 158295 | ||||||
| 7 | 41 | ||||||
| 15 | 7 | 7 | 16736 | use URI::Escape; | |||
| 7 | 7864 | ||||||
| 7 | 451 | ||||||
| 16 | 7 | 7 | 3157 | use Filesys::Virtual::Plain; | |||
| 7 | 68246 | ||||||
| 7 | 215 | ||||||
| 17 | 7 | 7 | 2979 | use MIME::Types; | |||
| 7 | 37275 | ||||||
| 7 | 453 | ||||||
| 18 | 7 | 7 | 4364 | use Storable; | |||
| 7 | 16232 | ||||||
| 7 | 392 | ||||||
| 19 | 7 | 7 | 122 | use File::Basename; | |||
| 7 | 9 | ||||||
| 7 | 13124 | ||||||
| 20 | |||||||
| 21 | sub spawn { | ||||||
| 22 | 7 | 7 | 1 | 106 | my $package = shift; | ||
| 23 | 7 | 50 | 31 | croak "$package needs an even number of parameters" if @_ & 1; | |||
| 24 | 7 | 26 | my %params = @_; | ||||
| 25 | |||||||
| 26 | 7 | 56 | $params{lc $_} = delete $params{$_} for keys %params; | ||||
| 27 | |||||||
| 28 | die "$package requires a 'root_dir' argument\n" | ||||||
| 29 | 7 | 50 | 33 | 180 | unless $params{root_dir} and -d $params{root_dir}; | ||
| 30 | |||||||
| 31 | 7 | 50 | 33 | _massage_handlers( $params{handlers} ) if $params{handlers}; | |||
| 32 | 7 | 50 | 30 | $params{handlers} = { } unless $params{handlers}; | |||
| 33 | |||||||
| 34 | 7 | 15 | my $options = delete $params{'options'}; | ||||
| 35 | |||||||
| 36 | 7 | 19 | my $self = bless \%params, $package; | ||||
| 37 | |||||||
| 38 | $self->{vdir} = Filesys::Virtual::Plain->new( { root_path => $self->{root_dir} } ) | ||||||
| 39 | 7 | 50 | 127 | or die "Could not create a Filesys::Virtual::Plain object for $self->{root_dir}\n"; | |||
| 40 | |||||||
| 41 | 7 | 629 | $self->{mt} = MIME::Types->new(); | ||||
| 42 | |||||||
| 43 | 7 | 50 | 33 | 269392 | $self->{auto_index} = 1 unless defined ( $self->{auto_index} ) and $self->{auto_index} == 0; | ||
| 44 | 7 | 50 | 42 | $self->{index_file} = 'index.html' unless $self->{index_file}; | |||
| 45 | |||||||
| 46 | 7 | 100 | 30 | $self->{prefix_fix} = delete $self->{alias_path} if $self->{alias_path}; | |||
| 47 | |||||||
| 48 | 7 | 100 | 29 | $self->{prefix_fix} = quotemeta( $self->{prefix_fix} ) if $self->{prefix_fix}; | |||
| 49 | |||||||
| 50 | 7 | 14 | my $mm; | ||||
| 51 | |||||||
| 52 | 7 | 14 | eval { | ||||
| 53 | 7 | 1611 | require File::LibMagic; | ||||
| 54 | 0 | 0 | $mm = File::MMagic->new(); | ||||
| 55 | }; | ||||||
| 56 | |||||||
| 57 | 7 | 36 | $self->{mm} = $mm; | ||||
| 58 | |||||||
| 59 | 7 | 50 | 33 | 181 | $self->{session_id} = POE::Session->create( | ||
| 60 | object_states => [ | ||||||
| 61 | $self => { | ||||||
| 62 | request => '_request', | ||||||
| 63 | shutdown => '_shutdown', | ||||||
| 64 | -input => '_read_input', | ||||||
| 65 | -error => '_read_error', | ||||||
| 66 | }, | ||||||
| 67 | $self => [ qw(_start) ], | ||||||
| 68 | ], | ||||||
| 69 | ( ( defined ( $options ) and ref ( $options ) eq 'HASH' ) ? ( options => $options ) : () ), | ||||||
| 70 | )->ID(); | ||||||
| 71 | |||||||
| 72 | 7 | 929 | return $self; | ||||
| 73 | } | ||||||
| 74 | |||||||
| 75 | sub _start { | ||||||
| 76 | 7 | 7 | 1833 | my ($kernel,$self) = @_[KERNEL,OBJECT]; | |||
| 77 | |||||||
| 78 | 7 | 32 | $self->{session_id} = $_[SESSION]->ID(); | ||||
| 79 | |||||||
| 80 | 7 | 50 | 47 | if ( $self->{alias} ) { | |||
| 81 | 0 | 0 | $kernel->alias_set( $self->{alias} ); | ||||
| 82 | } else { | ||||||
| 83 | 7 | 196 | $kernel->refcount_increment( $self->{session_id} => __PACKAGE__ ); | ||||
| 84 | } | ||||||
| 85 | |||||||
| 86 | 7 | 236 | return; | ||||
| 87 | } | ||||||
| 88 | |||||||
| 89 | sub request { | ||||||
| 90 | 30 | 30 | 1 | 44909 | my $self = shift; | ||
| 91 | 30 | 76 | $poe_kernel->post( $self->session_id() => 'request' => @_ ); | ||||
| 92 | } | ||||||
| 93 | |||||||
| 94 | sub _request { | ||||||
| 95 | 30 | 30 | 4198 | my ($kernel,$self,$request,$response) = @_[KERNEL,OBJECT,ARG0 .. ARG1]; | |||
| 96 | 30 | 69 | my $sender = $_[SENDER]->ID(); | ||||
| 97 | |||||||
| 98 | # Sanity check the $request and $response objects *sigh* | ||||||
| 99 | 30 | 50 | 33 | 315 | return unless $response and $response->isa("HTTP::Response"); | ||
| 100 | |||||||
| 101 | 30 | 50 | 33 | 162 | unless ( $request and $request->isa("HTTP::Request") ) { | ||
| 102 | 0 | 0 | $kernel->post( $sender => 'DONE' => $response ); | ||||
| 103 | 0 | 0 | return; | ||||
| 104 | } | ||||||
| 105 | |||||||
| 106 | 30 | 85 | my $path = uri_unescape( $request->uri->path ); | ||||
| 107 | 30 | 930 | my $realpath = $path; | ||||
| 108 | |||||||
| 109 | 30 | 100 | 85 | $realpath = $self->{prefix_path} . $path if $self->{prefix_path}; | |||
| 110 | 30 | 100 | 133 | $realpath =~ s/^$self->{prefix_fix}// if $self->{prefix_fix}; | |||
| 111 | |||||||
| 112 | SWITCH: { | ||||||
| 113 | 30 | 100 | 32 | if ( $self->{vdir}->test('d', $realpath) ) { | |||
| 30 | 123 | ||||||
| 114 | 18 | 100 | 2156 | if ( $path !~ /\/$/ ) { | |||
| 115 | 6 | 13 | $path .= '/'; | ||||
| 116 | 6 | 28 | $response = $self->_generate_301( $path, $response ); | ||||
| 117 | 6 | 16 | last SWITCH; | ||||
| 118 | } | ||||||
| 119 | 12 | 50 | 33 | 47 | if ( $self->{auto_index} and !$self->{vdir}->test('e', $realpath . $self->{index_file} ) ) { | ||
| 120 | 0 | 0 | $response = $self->_generate_dir_listing( $path, $response ); | ||||
| 121 | 0 | 0 | last SWITCH; | ||||
| 122 | } | ||||||
| 123 | 12 | 100 | 57 | if ( $self->{vdir}->test('e', $realpath . $self->{index_file} ) ) { | |||
| 124 | 6 | 617 | my ($filename, $directory, $suffix) = fileparse($self->{index_file}, keys %{ $self->{handlers} } ); | ||||
| 6 | 251 | ||||||
| 125 | 6 | 50 | 25 | if ( $suffix ) { | |||
| 126 | $kernel->post( | ||||||
| 127 | $self->{handlers}->{ $suffix }->{SESSION}, | ||||||
| 128 | $self->{handlers}->{ $suffix }->{EVENT}, | ||||||
| 129 | { | ||||||
| 130 | request => $request, | ||||||
| 131 | response => $response, | ||||||
| 132 | session => $sender, | ||||||
| 133 | script_name => $path . $self->{index_file}, | ||||||
| 134 | script_filename => $self->{vdir}->root_path() . $realpath . $self->{index_file}, | ||||||
| 135 | }, | ||||||
| 136 | 0 | 0 | ); | ||||
| 137 | 0 | 0 | return; | ||||
| 138 | } | ||||||
| 139 | 6 | 41 | $response = $self->_generate_content( $sender, $path . $self->{index_file}, $response ); | ||||
| 140 | 6 | 15 | last SWITCH; | ||||
| 141 | } | ||||||
| 142 | 6 | 548 | $response = $self->_generate_403( $response ); | ||||
| 143 | 6 | 17 | last SWITCH; | ||||
| 144 | } | ||||||
| 145 | 12 | 100 | 1232 | if ( $self->{vdir}->test('e', $realpath) ) { | |||
| 146 | 3 | 270 | my ($filename, $directory, $suffix) = fileparse($realpath, keys %{ $self->{handlers} } ); | ||||
| 3 | 90 | ||||||
| 147 | 3 | 50 | 11 | if ( $suffix ) { | |||
| 148 | $kernel->post( | ||||||
| 149 | $self->{handlers}->{ $suffix }->{SESSION}, | ||||||
| 150 | $self->{handlers}->{ $suffix }->{EVENT}, | ||||||
| 151 | { | ||||||
| 152 | request => $request, | ||||||
| 153 | response => $response, | ||||||
| 154 | session => $sender, | ||||||
| 155 | script_name => $path, | ||||||
| 156 | 3 | 17 | script_filename => $self->{vdir}->root_path() . $realpath, | ||||
| 157 | }, | ||||||
| 158 | ); | ||||||
| 159 | 3 | 239 | return; | ||||
| 160 | } | ||||||
| 161 | 0 | 0 | $response = $self->_generate_content( $sender, $path, $response ); | ||||
| 162 | 0 | 0 | last SWITCH; | ||||
| 163 | } | ||||||
| 164 | 9 | 797 | $response = $self->_generate_404( $response ); | ||||
| 165 | } | ||||||
| 166 | |||||||
| 167 | 27 | 100 | 129 | $kernel->post( $sender => 'DONE' => $response ) if defined $response; | |||
| 168 | 27 | 1793 | undef; | ||||
| 169 | } | ||||||
| 170 | |||||||
| 171 | sub shutdown { | ||||||
| 172 | 7 | 7 | 1 | 4028 | my $self = shift; | ||
| 173 | 7 | 28 | $poe_kernel->post( $self->session_id() => 'shutdown' => @_ ); | ||||
| 174 | } | ||||||
| 175 | |||||||
| 176 | sub _shutdown { | ||||||
| 177 | 7 | 7 | 1349 | my ($kernel,$self) = @_[KERNEL,OBJECT]; | |||
| 178 | |||||||
| 179 | 7 | 50 | 26 | if ( $self->{alias} ) { | |||
| 180 | 0 | 0 | $kernel->alias_remove( $_ ) for $kernel->alias_list(); | ||||
| 181 | } else { | ||||||
| 182 | 7 | 34 | $kernel->refcount_decrement( $self->{session_id} => __PACKAGE__ ); | ||||
| 183 | } | ||||||
| 184 | 7 | 289 | undef; | ||||
| 185 | } | ||||||
| 186 | |||||||
| 187 | sub session_id { | ||||||
| 188 | 37 | 37 | 1 | 161 | return $_[0]->{session_id}; | ||
| 189 | } | ||||||
| 190 | |||||||
| 191 | # Alias for deprecated function | ||||||
| 192 | sub autoindex { | ||||||
| 193 | 0 | 0 | 0 | 0 | warn "autoindex is deprecated: please use auto_index"; | ||
| 194 | 0 | 0 | goto &auto_index; | ||||
| 195 | } | ||||||
| 196 | |||||||
| 197 | sub auto_index { | ||||||
| 198 | 6 | 6 | 1 | 3251 | my $self = shift; | ||
| 199 | 6 | 8 | my $value = shift; | ||||
| 200 | 6 | 50 | 26 | return $self->{auto_index} unless defined $value; | |||
| 201 | 6 | 16 | $self->{auto_index} = $value; | ||||
| 202 | } | ||||||
| 203 | |||||||
| 204 | sub index_file { | ||||||
| 205 | 0 | 0 | 1 | 0 | my $self = shift; | ||
| 206 | 0 | 0 | my $value = shift; | ||||
| 207 | 0 | 0 | 0 | return $self->{index_file} unless defined $value; | |||
| 208 | 0 | 0 | $self->{index_file} = $value; | ||||
| 209 | } | ||||||
| 210 | |||||||
| 211 | sub _generate_404 { | ||||||
| 212 | 9 | 9 | 16 | my $self = shift; | |||
| 213 | 9 | 50 | 47 | my $response = shift || return; | |||
| 214 | 9 | 28 | return generate_404( $response ); | ||||
| 215 | } | ||||||
| 216 | |||||||
| 217 | sub generate_404 { | ||||||
| 218 | 9 | 50 | 9 | 1 | 27 | my $response = shift || return; | |
| 219 | 9 | 50 | 49 | return unless $response->isa('HTTP::Response'); | |||
| 220 | 9 | 36 | $response->code( 404 ); | ||||
| 221 | 9 | 128 | $response->header( 'Content-Type', 'text/html' ); | ||||
| 222 | 9 | 492 | $response->content( start_html('404') . h1('Not Found') . end_html ); | ||||
| 223 | 9 | 19287 | return $response; | ||||
| 224 | } | ||||||
| 225 | |||||||
| 226 | sub _generate_403 { | ||||||
| 227 | 6 | 6 | 12 | my $self = shift; | |||
| 228 | 6 | 50 | 21 | my $response = shift || return; | |||
| 229 | 6 | 26 | return generate_403( $response ); | ||||
| 230 | } | ||||||
| 231 | |||||||
| 232 | sub generate_403 { | ||||||
| 233 | 6 | 50 | 6 | 1 | 19 | my $response = shift || return; | |
| 234 | 6 | 50 | 29 | return unless $response->isa('HTTP::Response'); | |||
| 235 | 6 | 28 | $response->code( 403 ); | ||||
| 236 | 6 | 67 | $response->header( 'Content-Type', 'text/html' ); | ||||
| 237 | 6 | 258 | $response->content( start_html('403') . h1('Forbidden') . end_html ); | ||||
| 238 | 6 | 1049 | return $response; | ||||
| 239 | } | ||||||
| 240 | |||||||
| 241 | sub _generate_301 { | ||||||
| 242 | 6 | 6 | 12 | my $self = shift; | |||
| 243 | 6 | 50 | 22 | my $path = shift || return; | |||
| 244 | 6 | 50 | 22 | my $response = shift || return; | |||
| 245 | 6 | 20 | return generate_301( $path, $response ); | ||||
| 246 | } | ||||||
| 247 | |||||||
| 248 | sub generate_301 { | ||||||
| 249 | 6 | 50 | 6 | 1 | 19 | my $path = shift || return; | |
| 250 | 6 | 50 | 19 | my $response = shift || return; | |||
| 251 | 6 | 50 | 30 | return unless $response->isa('HTTP::Response'); | |||
| 252 | 6 | 28 | $response->code( 301 ); | ||||
| 253 | 6 | 109 | $response->header( 'Location' => $path ); | ||||
| 254 | 6 | 504 | $response->header( 'Content-Type', 'text/html' ); | ||||
| 255 | 6 | 199 | $response->content( start_html('301') . h1('Moved Permanently') . ' The document has moved here. ' . end_html ); |
||||
| 256 | 6 | 15652 | return $response; | ||||
| 257 | } | ||||||
| 258 | |||||||
| 259 | sub _generate_dir_listing { | ||||||
| 260 | 0 | 0 | 0 | my $self = shift; | |||
| 261 | 0 | 0 | 0 | my $path = shift || return; | |||
| 262 | 0 | 0 | 0 | my $response = shift || return undef; | |||
| 263 | 0 | 0 | my $content = start_html('Index of ' . $path) . h1('Index of ' . $path) . qq{ \n
|
||||
| 264 | |||||||
| 265 | 0 | 0 | my $realpath = $path; | ||||
| 266 | 0 | 0 | 0 | $realpath = $self->{prefix_path} . $path if $self->{prefix_path}; | |||
| 267 | 0 | 0 | 0 | $realpath =~ s/^$self->{prefix_fix}// if $self->{prefix_fix}; | |||
| 268 | |||||||
| 269 | 0 | 0 | foreach my $item ( $self->{vdir}->list( $realpath ) ) { | ||||
| 270 | 0 | 0 | 0 | next if $item =~ /^\./; | |||
| 271 | 0 | 0 | $content .= qq{ |
||||
| 272 | } | ||||||
| 273 | |||||||
| 274 | 0 | 0 | $content .= qq{\n} . end_html; | ||||
| 275 | 0 | 0 | $response->code( 200 ); | ||||
| 276 | 0 | 0 | $response->header( 'Content-Type', 'text/html' ); | ||||
| 277 | 0 | 0 | $response->content( $content ); | ||||
| 278 | 0 | 0 | return $response; | ||||
| 279 | } | ||||||
| 280 | |||||||
| 281 | sub _read_input { | ||||||
| 282 | 6 | 6 | 1569 | ${ $_[OBJECT]{read}{$_[ARG1]}{content} } .= $_[ARG0]; | |||
| 6 | 38 | ||||||
| 283 | } | ||||||
| 284 | |||||||
| 285 | # Read finished | ||||||
| 286 | sub _read_error { | ||||||
| 287 | 6 | 6 | 15019 | my ($self, $kernel, $error, $wheelid) = @_[ OBJECT, KERNEL, ARG1, ARG3 ]; | |||
| 288 | 6 | 20 | my $read = delete $self->{read}{$wheelid}; | ||||
| 289 | 6 | 15 | my $response = delete $read->{response}; | ||||
| 290 | 6 | 14 | my $content = delete $read->{content}; | ||||
| 291 | 6 | 14 | my $mimetype = delete $read->{mimetype}; | ||||
| 292 | 6 | 16 | my $sender = delete $read->{sender}; | ||||
| 293 | |||||||
| 294 | 6 | 37 | delete $read->{wheel}; | ||||
| 295 | |||||||
| 296 | 6 | 50 | 1245 | if ($error) { | |||
| 297 | 0 | 0 | $response->content("Internal Server Error"); | ||||
| 298 | 0 | 0 | $response->code(500); | ||||
| 299 | } | ||||||
| 300 | else { | ||||||
| 301 | 6 | 50 | 41 | unless ( $mimetype ) { | |||
| 302 | 0 | 0 | 0 | if ( $self->{mm} ) { | |||
| 303 | 0 | 0 | $mimetype = $self->{mm}->checktype_contents( $$content ); | ||||
| 304 | } | ||||||
| 305 | else { | ||||||
| 306 | 0 | 0 | $mimetype = 'application/octet-stream'; | ||||
| 307 | } | ||||||
| 308 | } | ||||||
| 309 | 6 | 80 | $response->code( 200 ); | ||||
| 310 | 6 | 101 | $response->content_type( $mimetype ); | ||||
| 311 | 6 | 224 | $response->content_ref( $content ); | ||||
| 312 | } | ||||||
| 313 | |||||||
| 314 | 6 | 109 | $kernel->post( $sender => 'DONE' => $response ); | ||||
| 315 | } | ||||||
| 316 | |||||||
| 317 | sub _generate_content { | ||||||
| 318 | 6 | 6 | 13 | my $self = shift; | |||
| 319 | 6 | 50 | 24 | my $sender = shift || return; | |||
| 320 | 6 | 50 | 29 | my $path = shift || return; | |||
| 321 | 6 | 50 | 23 | my $response = shift || return; | |||
| 322 | 6 | 9 | my $realpath = $path; | ||||
| 323 | 6 | 100 | 32 | $realpath = $self->{prefix_path} . $path if $self->{prefix_path}; | |||
| 324 | 6 | 100 | 36 | $realpath =~ s/^$self->{prefix_fix}// if $self->{prefix_fix}; | |||
| 325 | |||||||
| 326 | 6 | 41 | my $mimetype = $self->{mt}->mimeTypeOf( $path ); | ||||
| 327 | |||||||
| 328 | 6 | 50 | 825 | if ( my $fh = $self->{vdir}->open_read( $realpath ) ) { | |||
| 329 | 6 | 806 | binmode($fh); | ||||
| 330 | 6 | 50 | 33 | 50 | if ( $^O eq 'MSWin32' or $self->{blocking} ) { | ||
| 331 | 0 | 0 | local $/ = undef; | ||||
| 332 | 0 | 0 | my $content = <$fh>; | ||||
| 333 | 0 | 0 | 0 | unless ( $mimetype ) { | |||
| 334 | 0 | 0 | 0 | if ( $self->{mm} ) { | |||
| 335 | 0 | 0 | $mimetype = $self->{mm}->checktype_contents( $content ); | ||||
| 336 | } | ||||||
| 337 | else { | ||||||
| 338 | 0 | 0 | $mimetype = 'application/octet-stream'; | ||||
| 339 | } | ||||||
| 340 | } | ||||||
| 341 | 0 | 0 | $response->code( 200 ); | ||||
| 342 | 0 | 0 | $response->content_type( $mimetype ); | ||||
| 343 | 0 | 0 | $response->content_ref( \$content ); | ||||
| 344 | } else { | ||||||
| 345 | 6 | 65 | my $readwrite = POE::Wheel::ReadWrite->new( | ||||
| 346 | Handle => $fh, | ||||||
| 347 | Filter => POE::Filter::Stream->new(), | ||||||
| 348 | InputEvent => "-input", | ||||||
| 349 | ErrorEvent => "-error", | ||||||
| 350 | ); | ||||||
| 351 | |||||||
| 352 | 6 | 1994 | my $content = ""; | ||||
| 353 | |||||||
| 354 | 6 | 39 | my $wheelid = $readwrite->ID; | ||||
| 355 | 6 | 75 | my $readheap = { | ||||
| 356 | wheel => $readwrite, | ||||||
| 357 | response => $response, | ||||||
| 358 | mimetype => $mimetype, | ||||||
| 359 | sender => $sender, | ||||||
| 360 | content => \$content, | ||||||
| 361 | }; | ||||||
| 362 | |||||||
| 363 | 6 | 18 | $self->{read}{$wheelid} = $readheap; | ||||
| 364 | |||||||
| 365 | 6 | 15 | return; | ||||
| 366 | } | ||||||
| 367 | } else { | ||||||
| 368 | 0 | 0 | $response = $self->_generate_404( $response ); | ||||
| 369 | } | ||||||
| 370 | |||||||
| 371 | 0 | 0 | return $response; | ||||
| 372 | } | ||||||
| 373 | |||||||
| 374 | sub _massage_handlers { | ||||||
| 375 | 3 | 50 | 3 | 8 | my $handler = shift || return; | ||
| 376 | 3 | 50 | 33 | 21 | croak( "HANDLERS is not a ref to an hash!" ) | ||
| 377 | unless ref $handler and ref $handler eq 'HASH'; | ||||||
| 378 | 3 | 5 | foreach my $ext ( keys %{ $handler } ) { | ||||
| 3 | 10 | ||||||
| 379 | 3 | 50 | 11 | delete $handler->{ $ext } unless ref $handler->{ $ext } eq 'HASH'; | |||
| 380 | croak( "HANDLER for '$ext' does not have a SESSION argument!" ) | ||||||
| 381 | 3 | 50 | 12 | unless $handler->{ $ext }->{'SESSION'}; | |||
| 382 | croak( "HANDLER for '$ext' does not have an EVENT argument!" ) | ||||||
| 383 | 3 | 50 | 18 | unless $handler->{ $ext }->{'EVENT'}; | |||
| 384 | $handler->{ $ext }->{'SESSION'} = $handler->{ $ext }->{'SESSION'}->ID() | ||||||
| 385 | 3 | 50 | 17 | if UNIVERSAL::isa( $handler->{ $ext }->{'SESSION'}, 'POE::Session' ); | |||
| 386 | } | ||||||
| 387 | 3 | 6 | return 1; | ||||
| 388 | } | ||||||
| 389 | |||||||
| 390 | sub get_handlers { | ||||||
| 391 | 0 | 0 | 1 | 0 | my $self = shift; | ||
| 392 | 0 | 0 | my $handlers = Storable::dclone( $self->{handlers} ); | ||||
| 393 | 0 | 0 | return $handlers; | ||||
| 394 | } | ||||||
| 395 | |||||||
| 396 | sub set_handlers { | ||||||
| 397 | 3 | 3 | 1 | 2690 | my $self = shift; | ||
| 398 | 3 | 50 | 9 | my $handlers = shift || return; | |||
| 399 | 3 | 9 | _massage_handlers( $handlers ); | ||||
| 400 | 3 | 3 | $self->{handlers} = $handlers; | ||||
| 401 | 3 | 6 | return 1; | ||||
| 402 | } | ||||||
| 403 | |||||||
| 404 | qq[Content Simples]; | ||||||
| 405 | |||||||
| 406 | __END__ |