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 30     30   26829877 use strict;
  30         42  
  30         721  
4 30     30   102 use warnings;
  30         34  
  30         694  
5 30     30   99 use base 'FusionInventory::Agent::HTTP::Client';
  30         76  
  30         6911  
6              
7 30     30   127 use English qw(-no_match_vars);
  30         35  
  30         160  
8 30     30   8482 use HTTP::Request;
  30         37  
  30         342  
9 30     30   517 use UNIVERSAL::require;
  30         33  
  30         144  
10 30     30   425 use URI;
  30         35  
  30         196  
11 30     30   501 use Encode;
  30         36  
  30         1805  
12              
13 30     30   110 use FusionInventory::Agent::Tools;
  30         36  
  30         3523  
14 30     30   10489 use FusionInventory::Agent::XML::Response;
  30         58  
  30         272  
15              
16             my $log_prefix = "[http client] ";
17              
18             sub new {
19 2     2 1 386 my ($class, %params) = @_;
20              
21 2         19 my $self = $class->SUPER::new(%params);
22              
23 2         8 $self->{ua}->default_header('Pragma' => 'no-cache');
24              
25             # check compression mode
26 2 50       88 if (Compress::Zlib->require()) {
    0          
27             # RFC 1950
28 2         69 $self->{compression} = 'zlib';
29 2         6 $self->{ua}->default_header('Content-type' => 'application/x-compress-zlib');
30             $self->{logger}->debug(
31 2         65 $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         5 return $self;
52             }
53              
54             sub send { ## no critic (ProhibitBuiltinHomonyms)
55 7     7 1 1022114 my ($self, %params) = @_;
56              
57             my $url = ref $params{url} eq 'URI' ?
58 7 50       90 $params{url} : URI->new($params{url});
59 7         7273 my $message = $params{message};
60 7         19 my $logger = $self->{logger};
61              
62 7         46 my $request_content = $message->getContent();
63 7         2822 $logger->debug2($log_prefix . "sending message:\n $request_content");
64              
65 7         25 $request_content = $self->_compress(encode('UTF-8', $request_content));
66 7 50       1637 if (!$request_content) {
67 0         0 $logger->error($log_prefix . 'inflating problem');
68 0         0 return;
69             }
70              
71 7         67 my $request = HTTP::Request->new(POST => $url);
72 7         501 $request->content($request_content);
73              
74 7         150 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       15 return if !$response->is_success();
79              
80 6         36 my $response_content = $response->content();
81 6 100       55 if (!$response_content) {
82 1         6 $logger->error($log_prefix . "unknown content format");
83 1         24 return;
84             }
85              
86 5         15 my $uncompressed_response_content = $self->_uncompress($response_content);
87 5 50       173 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         20 $logger->debug2($log_prefix . "receiving message:\n $uncompressed_response_content");
95              
96 5         6 my $result;
97 5         6 eval {
98 5         43 $result = FusionInventory::Agent::XML::Response->new(
99             content => $uncompressed_response_content
100             );
101             };
102 5 100       12 if ($EVAL_ERROR) {
103 2         7 my @lines = split(/\n/, $uncompressed_response_content);
104 2         12 $logger->error(
105             $log_prefix . "unexpected content, starting with $lines[0]"
106             );
107 2         34 return;
108             }
109              
110 3         28 return $result;
111             }
112              
113             sub _compress {
114 7     7   196 my ($self, $data) = @_;
115              
116             return
117             $self->{compression} eq 'zlib' ? $self->_compressZlib($data) :
118 7 0       38 $self->{compression} eq 'gzip' ? $self->_compressGzip($data) :
    50          
119             $data;
120             }
121              
122             sub _uncompress {
123 5     5   8 my ($self, $data) = @_;
124              
125 5 100       55 if ($data =~ /(\x78\x9C.*)/s) {
    50          
    50          
126 3         15 $self->{logger}->debug2("format: Zlib");
127 3         9 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         10 $self->{logger}->debug2("format: Plaintext");
133 2         7 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   21 my ($self, $data) = @_;
142              
143 8         33 return Compress::Zlib::compress($data);
144             }
145              
146             sub _compressGzip {
147 1     1   568 my ($self, $data) = @_;
148              
149 1         7 File::Temp->require();
150 1         6539 my $in = File::Temp->new();
151 1         435 print $in $data;
152 1         36 close $in;
153              
154             my $out = getFileHandle(
155             command => 'gzip -c ' . $in->filename(),
156             logger => $self->{logger}
157 1         5 );
158 1 50       22 return unless $out;
159              
160 1         8 local $INPUT_RECORD_SEPARATOR; # Set input to "slurp" mode.
161 1         1573 my $result = <$out>;
162 1         24 close $out;
163              
164 1         20 return $result;
165             }
166              
167             sub _uncompressZlib {
168 4     4   264 my ($self, $data) = @_;
169              
170 4         16 return Compress::Zlib::uncompress($data);
171             }
172              
173             sub _uncompressGzip {
174 1     1   161 my ($self, $data) = @_;
175              
176 1         10 my $in = File::Temp->new();
177 1         288 print $in $data;
178 1         24 close $in;
179              
180             my $out = getFileHandle(
181             command => 'gzip -dc ' . $in->filename(),
182             logger => $self->{logger}
183 1         6 );
184 1 50       11 return unless $out;
185              
186 1         8 local $INPUT_RECORD_SEPARATOR; # Set input to "slurp" mode.
187 1         1518 my $result = <$out>;
188 1         22 close $out;
189              
190 1         20 return $result;
191             }
192              
193             1;
194             __END__