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   132886 use 5.010;
  18         73  
2 18     18   107 use strict;
  18         28  
  18         396  
3 18     18   90 use warnings;
  18         34  
  18         474  
4 18     18   1846 use utf8;
  18         70  
  18         89  
5              
6             package Neo4j::Driver::Net::HTTP::LWP;
7             # ABSTRACT: HTTP network adapter for libwww-perl
8             $Neo4j::Driver::Net::HTTP::LWP::VERSION = '0.39';
9              
10 18     18   1217 use Carp qw(croak);
  18         43  
  18         1570  
11             our @CARP_NOT = qw(Neo4j::Driver::Net::HTTP);
12              
13 18     18   595 use JSON::MaybeXS 1.003003 qw();
  18         8568  
  18         576  
14 18     18   13248 use LWP::UserAgent 6.04 qw();
  18         785260  
  18         707  
15 18     18   151 use URI 1.31;
  18         263  
  18         19167  
16              
17             my $CONTENT_TYPE = 'application/json';
18              
19              
20             sub new {
21 19     19 1 26791 my ($class, $driver) = @_;
22            
23 19         108 my $self = bless {
24             json_coder => JSON::MaybeXS->new(utf8 => 1, allow_nonref => 0),
25             }, $class;
26            
27 19         465 my $uri = $driver->config('uri');
28 19 100       185 if (my $auth = $driver->config('auth')) {
29 8 100       83 croak "Only HTTP Basic Authentication is supported" if $auth->{scheme} ne 'basic';
30 7   100     26 my $userid = $auth->{principal} // '';
31 7   100     21 my $passwd = $auth->{credentials} // '';
32             my $userinfo = join ':', map {
33 7 100       15 utf8::encode $_ if utf8::is_utf8 $_; # uri_escape doesn't handle wide characters
  14         227  
34 14         38 URI::Escape::uri_escape $_;
35             } $userid, $passwd;
36 7         189 $uri = $uri->clone;
37 7         115 $uri->userinfo($userinfo);
38             }
39 18         537 $self->{uri_base} = $uri;
40            
41 18         34 my $version = $Neo4j::Driver::Net::HTTP::LWP::VERSION;
42 18 100       127 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         17316 $agent->default_headers->header( 'X-Stream' => 'true' );
48            
49 18 100       1190 if ($uri->scheme eq 'https') {
50 3   100     55 my $unencrypted = defined $driver->config('encrypted') && ! $driver->config('encrypted');
51 3 100       22 croak "HTTPS does not support unencrypted communication; use HTTP" if $unencrypted;
52 2         9 $agent->ssl_opts( verify_hostname => 1 );
53 2 100       55 if (defined( my $trust_ca = $driver->config('trust_ca') )) {
54 1 50       79 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       315 croak "HTTP does not support encrypted communication; use HTTPS" if $driver->config('encrypted');
60             }
61            
62 14         217 return $self;
63             }
64              
65              
66             sub protocol {
67             # uncoverable pod (see Deprecations.pod)
68 2     2 0 1295 my ($self) = @_;
69 2         49 warnings::warnif deprecated => __PACKAGE__ . "->protocol() is deprecated";
70 2   100     750 return $self->{response}->protocol // 'HTTP';
71             }
72              
73              
74             sub agent {
75             # uncoverable pod (see Deprecations.pod)
76 1     1 0 3024 my ($self) = @_;
77 1         41 warnings::warnif deprecated => __PACKAGE__ . "->agent() is deprecated; call ua() instead";
78 1         815 return $self->{agent};
79             }
80              
81              
82 3     3 1 1750 sub ua { shift->{agent} }
83              
84 7     7 1 4330 sub uri { shift->{uri_base} }
85              
86 2     2 1 2185 sub json_coder { shift->{json_coder} }
87              
88 5   100 5 1 1797 sub http_reason { shift->{response}->message // '' }
89              
90 2   100 2 1 1322 sub date_header { scalar shift->{response}->header('Date') // '' }
91              
92              
93             sub http_header {
94 13     13 1 7901 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     1418 if ( ! $header->{success} && $response->header('Client-Warning') // '' eq 'Internal response' ) {
      100        
102 3         139 $header->{content_type} = '';
103 3         6 $header->{status} = '';
104             }
105 13         330 return $header;
106             }
107              
108              
109             sub fetch_event {
110 596     596 1 5666 my ($self) = @_;
111 596 100       1263 $self->{buffer} = [grep { length } split m/\n|\x{1e}/, $self->fetch_all] unless defined $self->{buffer};
  939         6031  
112 596         736 return shift @{$self->{buffer}};
  596         1404  
113             }
114              
115              
116             sub fetch_all {
117 4     4 1 10138 my ($self) = @_;
118 4         17 return $self->{response}->content;
119             }
120              
121              
122             sub request {
123 6     6 1 25229 my ($self, $method, $url, $json, $accept, $mode) = @_;
124            
125 6         15 $self->{buffer} = undef;
126            
127 6         26 $url = URI->new_abs( $url, $self->{uri_base} );
128 6         1618 $method = lc $method;
129 6 100       18 if ($json) {
130             $self->{response} = $self->{agent}->$method(
131             $url,
132             'Accept' => $accept,
133 3 100       40 'Content' => $self->{json_coder}->encode($json),
134             'Content-Type' => $CONTENT_TYPE,
135             $mode ? ('Access-Mode' => $mode) : ()
136             );
137             }
138             else {
139 3         20 $self->{response} = $self->{agent}->$method(
140             $url,
141             'Accept' => $accept,
142             );
143             }
144             }
145              
146              
147             1;
148              
149             __END__