File Coverage

blib/lib/Search/Elasticsearch/Cxn/NetCurl.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1             package Search::Elasticsearch::Cxn::NetCurl;
2              
3 4     4   375954 use Moo;
  4         6  
  4         22  
4             with 'Search::Elasticsearch::Role::Cxn', 'Search::Elasticsearch::Role::Is_Sync';
5              
6 4     4   1206 use Search::Elasticsearch 5.00;
  4         130  
  4         203  
7             our $VERSION = "5.00";
8              
9 4     4   2286 use HTTP::Parser::XS qw(HEADERS_AS_HASHREF parse_http_response);
  4         3433  
  4         305  
10 4     4   25 use Try::Tiny;
  4         8  
  4         331  
11 0           use Net::Curl::Easy qw(
12             CURLOPT_HEADER
13             CURLOPT_VERBOSE
14             CURLOPT_URL
15             CURLOPT_CONNECTTIMEOUT_MS
16             CURLOPT_CUSTOMREQUEST
17             CURLOPT_TIMEOUT_MS
18             CURLOPT_POSTFIELDS
19             CURLOPT_POSTFIELDSIZE
20             CURLOPT_HTTPHEADER
21             CURLOPT_SSL_VERIFYPEER
22             CURLOPT_SSL_VERIFYHOST
23             CURLOPT_WRITEDATA
24             CURLOPT_HEADERDATA
25             CURLINFO_RESPONSE_CODE
26             CURLOPT_TCP_NODELAY
27 4     4   1026 );
  0            
28              
29             has 'connect_timeout' => ( is => 'ro', default => 2 );
30              
31             use namespace::clean;
32              
33             #===================================
34             sub perform_request {
35             #===================================
36             my ( $self, $params ) = @_;
37             my $uri = $self->build_uri($params);
38             my $method = $params->{method};
39              
40             my $handle = $self->handle;
41             $handle->reset;
42              
43             # $handle->setopt( CURLOPT_VERBOSE, 1 );
44              
45             $handle->setopt( CURLOPT_HEADER, 0 );
46             $handle->setopt( CURLOPT_TCP_NODELAY, 1 );
47             $handle->setopt( CURLOPT_URL, $uri );
48             $handle->setopt( CURLOPT_CUSTOMREQUEST, $method );
49              
50             $handle->setopt( CURLOPT_CONNECTTIMEOUT_MS, $self->connect_timeout * 1000 );
51             $handle->setopt( CURLOPT_TIMEOUT_MS,
52             1000 * ( $params->{timeout} || $self->request_timeout ) );
53              
54             my %headers = %{ $self->default_headers };
55              
56             my $data = $params->{data};
57             if ( defined $data ) {
58             $headers{'Content-Type'} = $params->{mime_type};
59             $headers{'Expect'} = '';
60             $headers{'Content-Encoding'} = $params->{encoding}
61             if $params->{encoding};
62             $handle->setopt( CURLOPT_POSTFIELDS, $data );
63             $handle->setopt( CURLOPT_POSTFIELDSIZE, length $data );
64             }
65              
66             $handle->setopt( CURLOPT_HTTPHEADER,
67             [ map { "$_: " . $headers{$_} } keys %headers ] )
68             if %headers;
69              
70             my %opts = %{ $self->handle_args };
71             if ( $self->is_https ) {
72             if ( $self->has_ssl_options ) {
73             %opts = ( %opts, %{ $self->ssl_options } );
74             }
75             else {
76             %opts = (
77             %opts,
78             ( CURLOPT_SSL_VERIFYPEER() => 0,
79             CURLOPT_SSL_VERIFYHOST() => 0
80             )
81             );
82             }
83             }
84              
85             for ( keys %opts ) {
86             $handle->setopt( $_, $opts{$_} );
87             }
88              
89             my $content = my $head = '';
90             $handle->setopt( CURLOPT_WRITEDATA, \$content );
91             $handle->setopt( CURLOPT_HEADERDATA, \$head );
92              
93             my ( $code, $msg, $headers );
94              
95             try {
96             $handle->perform;
97             ( undef, undef, $code, $msg, $headers )
98             = parse_http_response( $head, HEADERS_AS_HASHREF );
99             }
100             catch {
101             $code = 509;
102             $msg = ( 0 + $_ ) . ": $_";
103             $msg . ", " . $handle->error
104             if $handle->error;
105             undef $content;
106             };
107              
108             return $self->process_response(
109             $params, # request
110             $code, # code
111             $msg, # msg
112             $content, # body
113             $headers # headers
114             );
115             }
116              
117             #===================================
118             sub error_from_text {
119             #===================================
120             local $_ = $_[2];
121             shift;
122             return
123             m/^7:/ ? 'Cxn'
124             : m/^28:/ ? 'Timeout'
125             : m/^51:/ ? 'SSL'
126             : m/^55:/ ? 'ContentLength'
127             : 'Request';
128              
129             }
130              
131             #===================================
132             sub _build_handle { Net::Curl::Easy->new }
133             #===================================
134              
135             1;
136              
137             # ABSTRACT: A Cxn implementation which uses libcurl via Net::Curl
138              
139             __END__