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   138705 use 5.010;
  18         69  
2 18     18   90 use strict;
  18         43  
  18         468  
3 18     18   80 use warnings;
  18         39  
  18         442  
4 18     18   1934 use utf8;
  18         103  
  18         122  
5              
6             package Neo4j::Driver::Net::HTTP::LWP;
7             # ABSTRACT: HTTP network adapter for libwww-perl
8             $Neo4j::Driver::Net::HTTP::LWP::VERSION = '0.38';
9              
10 18     18   1195 use Carp qw(croak);
  18         44  
  18         1660  
11             our @CARP_NOT = qw(Neo4j::Driver::Net::HTTP);
12              
13 18     18   586 use JSON::MaybeXS 1.003003 qw();
  18         8516  
  18         485  
14 18     18   13509 use LWP::UserAgent 6.04 qw();
  18         763912  
  18         649  
15 18     18   155 use URI 1.31;
  18         262  
  18         18808  
16              
17             my $CONTENT_TYPE = 'application/json';
18              
19              
20             sub new {
21 19     19 1 25001 my ($class, $driver) = @_;
22            
23 19         116 my $self = bless {
24             json_coder => JSON::MaybeXS->new(utf8 => 1, allow_nonref => 0),
25             }, $class;
26            
27 19         424 my $uri = $driver->config('uri');
28 19 100       139 if (my $auth = $driver->config('auth')) {
29 8 100       86 croak "Only HTTP Basic Authentication is supported" if $auth->{scheme} ne 'basic';
30 7   100     27 my $userid = $auth->{principal} // '';
31 7   100     25 my $passwd = $auth->{credentials} // '';
32             my $userinfo = join ':', map {
33 7 100       12 utf8::encode $_ if utf8::is_utf8 $_; # uri_escape doesn't handle wide characters
  14         190  
34 14         39 URI::Escape::uri_escape $_;
35             } $userid, $passwd;
36 7         194 $uri = $uri->clone;
37 7         111 $uri->userinfo($userinfo);
38             }
39 18         560 $self->{uri_base} = $uri;
40            
41 18         37 my $version = $Neo4j::Driver::Net::HTTP::LWP::VERSION;
42 18 100       124 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         17072 $agent->default_headers->header( 'X-Stream' => 'true' );
48            
49 18 100       1262 if ($uri->scheme eq 'https') {
50 3   100     59 my $unencrypted = defined $driver->config('encrypted') && ! $driver->config('encrypted');
51 3 100       20 croak "HTTPS does not support unencrypted communication; use HTTP" if $unencrypted;
52 2         8 $agent->ssl_opts( verify_hostname => 1 );
53 2 100       57 if (defined( my $trust_ca = $driver->config('trust_ca') )) {
54 1 50       60 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       316 croak "HTTP does not support encrypted communication; use HTTPS" if $driver->config('encrypted');
60             }
61            
62 14         205 return $self;
63             }
64              
65              
66             sub protocol {
67             # uncoverable pod (see Deprecations.pod)
68 2     2 0 1536 my ($self) = @_;
69 2         44 warnings::warnif deprecated => __PACKAGE__ . "->protocol() is deprecated";
70 2   100     717 return $self->{response}->protocol // 'HTTP';
71             }
72              
73              
74             sub agent {
75             # uncoverable pod (see Deprecations.pod)
76 1     1 0 3461 my ($self) = @_;
77 1         51 warnings::warnif deprecated => __PACKAGE__ . "->agent() is deprecated; call ua() instead";
78 1         765 return $self->{agent};
79             }
80              
81              
82 3     3 1 2196 sub ua { shift->{agent} }
83              
84 7     7 1 5409 sub uri { shift->{uri_base} }
85              
86 2     2 1 2519 sub json_coder { shift->{json_coder} }
87              
88 5   100 5 1 2169 sub http_reason { shift->{response}->message // '' }
89              
90 2   100 2 1 1523 sub date_header { scalar shift->{response}->header('Date') // '' }
91              
92              
93             sub http_header {
94 13     13 1 9061 my $response = shift->{response};
95 13   100     40 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     1426 if ( ! $header->{success} && $response->header('Client-Warning') // '' eq 'Internal response' ) {
      100        
102 3         129 $header->{content_type} = '';
103 3         5 $header->{status} = '';
104             }
105 13         331 return $header;
106             }
107              
108              
109             sub fetch_event {
110 596     596 1 6356 my ($self) = @_;
111 596 100       1286 $self->{buffer} = [grep { length } split m/\n|\x{1e}/, $self->fetch_all] unless defined $self->{buffer};
  939         6118  
112 596         726 return shift @{$self->{buffer}};
  596         1364  
113             }
114              
115              
116             sub fetch_all {
117 4     4 1 11174 my ($self) = @_;
118 4         15 return $self->{response}->content;
119             }
120              
121              
122             sub request {
123 6     6 1 27613 my ($self, $method, $url, $json, $accept, $mode) = @_;
124            
125 6         15 $self->{buffer} = undef;
126            
127 6         24 $url = URI->new_abs( $url, $self->{uri_base} );
128 6         1693 $method = lc $method;
129 6 100       17 if ($json) {
130             $self->{response} = $self->{agent}->$method(
131             $url,
132             'Accept' => $accept,
133 3 100       35 'Content' => $self->{json_coder}->encode($json),
134             'Content-Type' => $CONTENT_TYPE,
135             $mode ? ('Access-Mode' => $mode) : ()
136             );
137             }
138             else {
139 3         18 $self->{response} = $self->{agent}->$method(
140             $url,
141             'Accept' => $accept,
142             );
143             }
144             }
145              
146              
147             1;
148              
149             __END__