File Coverage

lib/Neo4j/Driver/Net/HTTP/LWP.pm
Criterion Covered Total %
statement 78 79 98.7
branch 25 26 96.1
condition 24 24 100.0
subroutine 20 20 100.0
pod 10 12 100.0
total 157 161 98.7


line stmt bran cond sub pod time code
1 18     18   138463 use 5.010;
  18         61  
2 18     18   96 use strict;
  18         30  
  18         428  
3 18     18   97 use warnings;
  18         40  
  18         469  
4 18     18   1945 use utf8;
  18         68  
  18         87  
5              
6             package Neo4j::Driver::Net::HTTP::LWP;
7             # ABSTRACT: HTTP network adapter for libwww-perl
8             $Neo4j::Driver::Net::HTTP::LWP::VERSION = '0.40';
9              
10 18     18   1159 use Carp qw(croak);
  18         56  
  18         1554  
11             our @CARP_NOT = qw(Neo4j::Driver::Net::HTTP);
12              
13 18     18   614 use JSON::MaybeXS 1.003003 qw();
  18         8469  
  18         558  
14 18     18   14073 use LWP::UserAgent 6.04 qw();
  18         792751  
  18         609  
15 18     18   174 use URI 1.31;
  18         263  
  18         18987  
16              
17             my $CONTENT_TYPE = 'application/json';
18              
19              
20             sub new {
21 19     19 1 23157 my ($class, $driver) = @_;
22            
23 19         95 my $self = bless {
24             json_coder => JSON::MaybeXS->new(utf8 => 1, allow_nonref => 0),
25             }, $class;
26            
27 19         455 my $uri = $driver->config('uri');
28 19 100       184 if (my $auth = $driver->config('auth')) {
29 8 100       144 croak "Only HTTP Basic Authentication is supported" if $auth->{scheme} ne 'basic';
30 7   100     25 my $userid = $auth->{principal} // '';
31 7   100     20 my $passwd = $auth->{credentials} // '';
32             my $userinfo = join ':', map {
33 7 100       17 utf8::encode $_ if utf8::is_utf8 $_; # uri_escape doesn't handle wide characters
  14         194  
34 14         42 URI::Escape::uri_escape $_;
35             } $userid, $passwd;
36 7         213 $uri = $uri->clone;
37 7         110 $uri->userinfo($userinfo);
38             }
39 18         557 $self->{uri_base} = $uri;
40            
41 18         38 my $version = $Neo4j::Driver::Net::HTTP::LWP::VERSION;
42 18 100       120 my $agent = $self->{agent} = LWP::UserAgent->new(
43             # User-Agent: Neo4j-Driver/0.21 libwww-perl/6.52
44             agent => sprintf("Neo4j-Driver%s ", $version ? "/$version" : ""),
45             timeout => $driver->config('timeout'),
46             );
47 18         17812 $agent->default_headers->header( 'X-Stream' => 'true' );
48            
49 18 100       1217 if ($uri->scheme eq 'https') {
50 3   100     60 my $unencrypted = defined $driver->config('encrypted') && ! $driver->config('encrypted');
51 3 100       19 croak "HTTPS does not support unencrypted communication; use HTTP" if $unencrypted;
52 2         10 $agent->ssl_opts( verify_hostname => 1 );
53 2 100       53 if (defined( my $trust_ca = $driver->config('trust_ca') )) {
54 1 50       83 croak "trust_ca file '$trust_ca' can't be used: $!" if ! open(my $fh, '<', $trust_ca);
55 0         0 $agent->ssl_opts( SSL_ca_file => $trust_ca );
56             }
57             }
58             else {
59 15 100       353 croak "HTTP does not support encrypted communication; use HTTPS" if $driver->config('encrypted');
60             }
61            
62 14         223 return $self;
63             }
64              
65              
66             sub protocol {
67             # uncoverable pod (see Deprecations.pod)
68 2     2 0 1384 my ($self) = @_;
69 2         34 warnings::warnif deprecated => __PACKAGE__ . "->protocol() is deprecated";
70 2   100     719 return $self->{response}->protocol // 'HTTP';
71             }
72              
73              
74             sub agent {
75             # uncoverable pod (see Deprecations.pod)
76 1     1 0 3056 my ($self) = @_;
77 1         45 warnings::warnif deprecated => __PACKAGE__ . "->agent() is deprecated; call ua() instead";
78 1         854 return $self->{agent};
79             }
80              
81              
82 3     3 1 1800 sub ua { shift->{agent} }
83              
84 7     7 1 4355 sub uri { shift->{uri_base} }
85              
86 2     2 1 2273 sub json_coder { shift->{json_coder} }
87              
88 5   100 5 1 1857 sub http_reason { shift->{response}->message // '' }
89              
90 2   100 2 1 1387 sub date_header { scalar shift->{response}->header('Date') // '' }
91              
92              
93             sub http_header {
94 13     13 1 7882 my $response = shift->{response};
95 13   100     39 my $header = {
      100        
      100        
96             content_type => scalar $response->header('Content-Type') // '',
97             location => scalar $response->header('Location') // '',
98             status => $response->code // '',
99             success => $response->is_success,
100             };
101 13 100 100     1476 if ( ! $header->{success} && $response->header('Client-Warning') // '' eq 'Internal response' ) {
      100        
102 3         138 $header->{content_type} = '';
103 3         7 $header->{status} = '';
104             }
105 13         342 return $header;
106             }
107              
108              
109             sub fetch_event {
110 596     596 1 5719 my ($self) = @_;
111 596 100       1099 $self->{buffer} = [grep { length } split m/\n|\x{1e}/, $self->fetch_all] unless defined $self->{buffer};
  939         6058  
112 596         780 return shift @{$self->{buffer}};
  596         1748  
113             }
114              
115              
116             sub fetch_all {
117 4     4 1 9894 my ($self) = @_;
118 4         16 return $self->{response}->content;
119             }
120              
121              
122             sub request {
123 6     6 1 24990 my ($self, $method, $url, $json, $accept, $mode) = @_;
124            
125 6         16 $self->{buffer} = undef;
126            
127 6         25 $url = URI->new_abs( $url, $self->{uri_base} );
128 6         1637 $method = lc $method;
129 6 100       26 if ($json) {
130             $self->{response} = $self->{agent}->$method(
131             $url,
132             'Accept' => $accept,
133 3 100       51 'Content' => $self->{json_coder}->encode($json),
134             'Content-Type' => $CONTENT_TYPE,
135             $mode ? ('Access-Mode' => $mode) : ()
136             );
137             }
138             else {
139 3         21 $self->{response} = $self->{agent}->$method(
140             $url,
141             'Accept' => $accept,
142             );
143             }
144             }
145              
146              
147             1;
148              
149             __END__