File Coverage

blib/lib/Feersum.pm
Criterion Covered Total %
statement 55 60 91.6
branch 11 16 68.7
condition 8 17 47.0
subroutine 11 13 84.6
pod 4 4 100.0
total 89 110 80.9


line stmt bran cond sub pod time code
1             package Feersum;
2 140     140   19832447 use 5.014;
  140         568  
3 140     140   665 use strict;
  140         222  
  140         2933  
4 140     140   520 use warnings;
  140         293  
  140         6065  
5 140     140   66816 use EV ();
  140         290081  
  140         4025  
6 140     140   780 use Carp ();
  140         177  
  140         1644  
7 140     140   2294 use Socket ();
  140         19393  
  140         8988  
8              
9             our $VERSION = '1.506_43';
10              
11             require Feersum::Connection;
12             require Feersum::Connection::Handle;
13             require XSLoader;
14             XSLoader::load('Feersum', $VERSION);
15              
16             # numify as per
17             # http://www.dagolden.com/index.php/369/version-numbers-should-be-boring/
18             $VERSION = eval $VERSION; ## no critic (StringyEval, ConstantVersion)
19              
20             our $INSTANCE;
21             my %_SOCKETS; # inside-out storage for socket refs (keyed by Scalar::Util::refaddr)
22              
23 140     140   544 use Scalar::Util ();
  140         169  
  140         1939  
24 140     140   488 use Exporter 'import';
  140         265  
  140         69978  
25             our @EXPORT_OK = qw(HEADER_NORM_SKIP HEADER_NORM_UPCASE HEADER_NORM_LOCASE HEADER_NORM_UPCASE_DASH HEADER_NORM_LOCASE_DASH);
26              
27             sub new {
28 195 100   195 1 25175099 unless ($INSTANCE) {
29 127         5700 $INSTANCE = __PACKAGE__->_xs_default_server();
30 127         2167 $SIG{PIPE} = 'IGNORE';
31             }
32 195         774 return $INSTANCE;
33             }
34             *endjinn = *new;
35              
36             sub new_instance {
37 79     79 1 69061082 my $class = shift;
38 79         1228 $SIG{PIPE} = 'IGNORE';
39 79         2788 return $class->_xs_new_server();
40             }
41              
42             sub DESTROY {
43 0     0   0 my $self = shift;
44 0         0 my $addr = Scalar::Util::refaddr($self);
45 0         0 delete $_SOCKETS{$addr};
46             # XS DESTROY is renamed to _xs_destroy and called here
47 0         0 $self->_xs_destroy();
48             }
49              
50             sub use_socket {
51 222     222 1 1854436 my ($self, $sock) = @_;
52 222         627 my $addr = Scalar::Util::refaddr($self);
53 222         337 push @{$_SOCKETS{$addr}}, $sock; # keep ref to prevent GC
  222         1006  
54 222         620 my $fd = fileno $sock;
55 222 50       761 Carp::croak "Invalid socket: fileno returned undef" unless defined $fd;
56 222         9173 $self->accept_on_fd($fd);
57              
58             # Try socket methods first, fall back to getsockname() for raw sockets
59 222         735 my ($host, $port) = ('localhost', 80);
60 222 100       2261 if ($sock->can('sockhost')) {
61 219   50     401 $host = eval { $sock->sockhost() } || 'localhost';
62 219   50     7722 $port = eval { $sock->sockport() } || 80; ## no critic (MagicNumbers)
63             } else {
64             # Raw socket (e.g., from Runner with SO_REUSEPORT) - use getsockname
65 3         15 my $sockaddr = getsockname($sock);
66 3 50       9 if ($sockaddr) {
67 3         5 my $family = eval { Socket::sockaddr_family($sockaddr) };
  3         12  
68 3 100 66     17 if (defined $family && $family == Socket::AF_INET()) {
    50 33        
      33        
69 2         7 (my $packed_port, my $packed_addr) = Socket::sockaddr_in($sockaddr);
70 2   50     20 $host = Socket::inet_ntoa($packed_addr) || 'localhost';
71             # Use defined check - port 0 is valid (OS-assigned dynamic port)
72 2 50       6 $port = defined($packed_port) ? $packed_port : 80;
73 1         4 } elsif (defined $family && eval { Socket::AF_INET6() } && $family == Socket::AF_INET6()) {
74 1         5 (my $packed_port, my $packed_addr) = Socket::sockaddr_in6($sockaddr);
75 1   50     15 $host = Socket::inet_ntop(Socket::AF_INET6(), $packed_addr) || 'localhost';
76             # Use defined check - port 0 is valid (OS-assigned dynamic port)
77 1 50       3 $port = defined($packed_port) ? $packed_port : 80;
78             }
79             }
80             }
81 222         4264 $self->set_server_name_and_port($host,$port);
82 222         529 return;
83             }
84              
85             # overload this to catch Feersum errors and exceptions thrown by request
86             # callbacks.
87 0     0 1   sub DIED { Carp::confess "DIED: $@"; }
88              
89             1;
90             __END__