File Coverage

blib/lib/FusionInventory/Agent/HTTP/Client/OCS.pm
Criterion Covered Total %
statement 98 112 87.5
branch 17 30 56.6
condition n/a
subroutine 18 18 100.0
pod 2 2 100.0
total 135 162 83.3


line stmt bran cond sub pod time code
1             package FusionInventory::Agent::HTTP::Client::OCS;
2              
3 29     29   29484047 use strict;
  29         69  
  29         832  
4 29     29   311 use warnings;
  29         63  
  29         984  
5 29     29   160 use base 'FusionInventory::Agent::HTTP::Client';
  29         126  
  29         11692  
6              
7 29     29   206 use English qw(-no_match_vars);
  29         76  
  29         200  
8 29     29   14344 use HTTP::Request;
  29         62  
  29         529  
9 29     29   741 use UNIVERSAL::require;
  29         56  
  29         205  
10 29     29   654 use URI;
  29         98  
  29         287  
11 29     29   18073 use Encode;
  29         224176  
  29         2835  
12              
13 29     29   12347 use FusionInventory::Agent::Tools;
  29         86  
  29         6000  
14 29     29   17638 use FusionInventory::Agent::XML::Response;
  29         289  
  29         449  
15              
16             my $log_prefix = "[http client] ";
17              
18             sub new {
19 2     2 1 196 my ($class, %params) = @_;
20              
21 2         25 my $self = $class->SUPER::new(%params);
22              
23 2         12 $self->{ua}->default_header('Pragma' => 'no-cache');
24              
25             # check compression mode
26 2 50       127 if (Compress::Zlib->require()) {
    0          
27             # RFC 1950
28 2         93 $self->{compression} = 'zlib';
29 2         9 $self->{ua}->default_header('Content-type' => 'application/x-compress-zlib');
30             $self->{logger}->debug(
31 2         95 $log_prefix .
32             'Using Compress::Zlib for compression'
33             );
34             } elsif (canRun('gzip')) {
35             # RFC 1952
36 0         0 $self->{compression} = 'gzip';
37 0         0 $self->{ua}->default_header('Content-type' => 'application/x-compress-gzip');
38             $self->{logger}->debug(
39 0         0 $log_prefix .
40             'Using gzip for compression'
41             );
42             } else {
43 0         0 $self->{compression} = 'none';
44 0         0 $self->{ua}->default_header('Content-type' => 'application/xml');
45             $self->{logger}->debug(
46 0         0 $log_prefix .
47             'Not using compression'
48             );
49             }
50              
51 2         10 return $self;
52             }
53              
54             sub send { ## no critic (ProhibitBuiltinHomonyms)
55 7     7 1 1036485 my ($self, %params) = @_;
56              
57             my $url = ref $params{url} eq 'URI' ?
58 7 50       186 $params{url} : URI->new($params{url});
59 7         15299 my $message = $params{message};
60 7         40 my $logger = $self->{logger};
61              
62 7         66 my $request_content = $message->getContent();
63 7         4746 $logger->debug2($log_prefix . "sending message:\n $request_content");
64              
65 7         35 $request_content = $self->_compress(encode('UTF-8', $request_content));
66 7 50       2904 if (!$request_content) {
67 0         0 $logger->error($log_prefix . 'inflating problem');
68 0         0 return;
69             }
70              
71 7         100 my $request = HTTP::Request->new(POST => $url);
72 7         720 $request->content($request_content);
73              
74 7         220 my $response = $self->request($request);
75              
76             # no need to log anything specific here, it has already been done
77             # in parent class
78 7 100       31 return if !$response->is_success();
79              
80 6         72 my $response_content = $response->content();
81 6 100       97 if (!$response_content) {
82 1         310 $logger->error($log_prefix . "unknown content format");
83 1         26 return;
84             }
85              
86 5         21 my $uncompressed_response_content = $self->_uncompress($response_content);
87 5 50       353 if (!$uncompressed_response_content) {
88 0         0 $logger->error(
89             $log_prefix . "uncompressed content, starting with: ".substr($response_content, 0, 500)
90             );
91 0         0 return;
92             }
93              
94 5         33 $logger->debug2($log_prefix . "receiving message:\n $uncompressed_response_content");
95              
96 5         10 my $result;
97 5         11 eval {
98 5         74 $result = FusionInventory::Agent::XML::Response->new(
99             content => $uncompressed_response_content
100             );
101             };
102 5 100       23 if ($EVAL_ERROR) {
103 2         11 my @lines = split(/\n/, $uncompressed_response_content);
104 2         19 $logger->error(
105             $log_prefix . "unexpected content, starting with $lines[0]"
106             );
107 2         70 return;
108             }
109              
110 3         57 return $result;
111             }
112              
113             sub _compress {
114 7     7   282 my ($self, $data) = @_;
115              
116             return
117             $self->{compression} eq 'zlib' ? $self->_compressZlib($data) :
118 7 0       89 $self->{compression} eq 'gzip' ? $self->_compressGzip($data) :
    50          
119             $data;
120             }
121              
122             sub _uncompress {
123 5     5   13 my ($self, $data) = @_;
124              
125 5 100       158 if ($data =~ /(\x78\x9C.*)/s) {
    50          
    50          
126 3         31 $self->{logger}->debug2("format: Zlib");
127 3         33 return $self->_uncompressZlib($1);
128             } elsif ($data =~ /(\x1F\x8B\x08.*)/s) {
129 0         0 $self->{logger}->debug2("format: Gzip");
130 0         0 return $self->_uncompressGzip($1);
131             } elsif ($data =~ /(<\/html>|)[^<]*(<.*>)\s*$/s) {
132 2         13 $self->{logger}->debug2("format: Plaintext");
133 2         10 return $2;
134             } else {
135 0         0 $self->{logger}->debug2("format: Unknown");
136 0         0 return;
137             }
138             }
139              
140             sub _compressZlib {
141 8     8   25 my ($self, $data) = @_;
142              
143 8         62 return Compress::Zlib::compress($data);
144             }
145              
146             sub _compressGzip {
147 1     1   607 my ($self, $data) = @_;
148              
149 1         9 File::Temp->require();
150 1         10619 my $in = File::Temp->new();
151 1         860 print $in $data;
152 1         58 close $in;
153              
154             my $out = getFileHandle(
155             command => 'gzip -c ' . $in->filename(),
156             logger => $self->{logger}
157 1         5 );
158 1 50       53 return unless $out;
159              
160 1         22 local $INPUT_RECORD_SEPARATOR; # Set input to "slurp" mode.
161 1         3469 my $result = <$out>;
162 1         37 close $out;
163              
164 1         42 return $result;
165             }
166              
167             sub _uncompressZlib {
168 4     4   456 my ($self, $data) = @_;
169              
170 4         27 return Compress::Zlib::uncompress($data);
171             }
172              
173             sub _uncompressGzip {
174 1     1   359 my ($self, $data) = @_;
175              
176 1         22 my $in = File::Temp->new();
177 1         578 print $in $data;
178 1         46 close $in;
179              
180             my $out = getFileHandle(
181             command => 'gzip -dc ' . $in->filename(),
182             logger => $self->{logger}
183 1         6 );
184 1 50       31 return unless $out;
185              
186 1         14 local $INPUT_RECORD_SEPARATOR; # Set input to "slurp" mode.
187 1         3383 my $result = <$out>;
188 1         44 close $out;
189              
190 1         244 return $result;
191             }
192              
193             1;
194             __END__