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