File Coverage

blib/lib/Archive/Har.pm
Criterion Covered Total %
statement 22 24 91.6
branch n/a
condition n/a
subroutine 8 8 100.0
pod n/a
total 30 32 93.7


line stmt bran cond sub pod time code
1             package Archive::Har;
2              
3 1     1   20696 use warnings;
  1         2  
  1         29  
4 1     1   5 use strict;
  1         1  
  1         24  
5 1     1   866 use English qw(-no_match_vars);
  1         4391  
  1         6  
6 1     1   983 use Archive::Har::Creator();
  1         3  
  1         19  
7 1     1   521 use Archive::Har::Browser();
  1         2  
  1         19  
8 1     1   537 use Archive::Har::Page();
  1         3  
  1         19  
9 1     1   544 use Archive::Har::Entry();
  1         3  
  1         23  
10 1     1   446 use XML::LibXML();
  0            
  0            
11             use IO::Compress::Gzip();
12             use IO::Uncompress::Gunzip();
13             use JSON();
14             use overload '""' => 'string';
15              
16             our $VERSION = '0.20';
17              
18             sub new {
19             my ( $class, $params ) = @_;
20             my $self = {};
21             bless $self, $class;
22             $self->_init();
23             return $self;
24             }
25              
26             sub _init {
27             my ($self) = @_;
28             foreach my $key ( keys %{$self} ) {
29             delete $self->{$key};
30             }
31             $self->{log} = {};
32             return;
33             }
34              
35             sub gzip {
36             my ( $self, $gzipped ) = @_;
37             my $uncompressed = $self->string();
38             my $old;
39             IO::Compress::Gzip::gzip( \$uncompressed, \$old,
40             -Level => IO::Compress::Gzip::Z_BEST_COMPRESSION() )
41             or
42             Carp::croak("Failed to gzip HAR archive:$IO::Compress::Gzip::GzipError");
43             if ( defined $gzipped ) {
44             my $string;
45             IO::Uncompress::Gunzip::gunzip( \$gzipped, \$string )
46             or Carp::croak('Failed to gunzip HAR archive');
47             $self->string($string);
48             }
49             return $old;
50             }
51              
52             sub hashref {
53             my ( $self, $ref ) = @_;
54             my $old = JSON->new()->utf8()->decode( $self->string() );
55             if ( ( @_ > 1 ) && ( defined $ref ) ) {
56             $self->_init();
57             $self->version( $ref->{log}->{version} );
58             $self->creator( Archive::Har::Creator->new( $ref->{log}->{creator} ) );
59             if ( defined $ref->{log}->{browser} ) {
60             $self->browser(
61             Archive::Har::Browser->new( $ref->{log}->{browser} ) );
62             }
63             if ( defined $ref->{log}->{pages} ) {
64             $self->pages( $ref->{log}->{pages} );
65             }
66             $self->entries( $ref->{log}->{entries} );
67             $self->comment( $ref->{log}->{comment} );
68             }
69             return $old;
70             }
71              
72             sub string {
73             my ( $self, $string ) = @_;
74             if ( defined $string ) {
75             my $utf8_regex = qr/\xef\xbb\xbf/smx;
76             my $utf16_regex = qr/(?:\xfe\xff|\xff\xfe)/smx;
77             my $utf32_regex = qr/(?:\x00\x00\xfe\xff|\xff\xfe\x00\x00)/smx;
78             $string =~ s/^(?:$utf8_regex|$utf16_regex|$utf32_regex)//smxg;
79             }
80             my $json = JSON->new();
81             $json = $json->utf8();
82             $json = $json->allow_blessed(1);
83             $json = $json->convert_blessed(1);
84             $json = $json->pretty();
85             $json = $json->canonical(1);
86             my $old = $json->encode($self);
87              
88             if ( ( @_ > 1 ) && ( defined $string ) ) {
89             my $ref = JSON->new()->utf8()->decode($string);
90             $self->hashref($ref);
91             }
92             return $old;
93             }
94              
95             sub _xml_creator {
96             my ( $self, $ie_log ) = @_;
97             foreach my $ie_creator ( $ie_log->getChildrenByTagName('creator') ) {
98             $self->creator( Archive::Har::Creator->new() );
99             foreach my $ie_name ( $ie_creator->getChildrenByTagName('name') ) {
100             $self->creator()->name( $ie_name->findvalue('text()') );
101             }
102             foreach my $ie_value ( $ie_creator->getChildrenByTagName('version') ) {
103             $self->creator()->version( $ie_value->findvalue('text()') );
104             }
105             }
106             return;
107             }
108              
109             sub _xml_browser {
110             my ( $self, $ie_log ) = @_;
111             foreach my $ie_browser ( $ie_log->getChildrenByTagName('browser') ) {
112             $self->browser( Archive::Har::Creator->new() );
113             foreach my $ie_name ( $ie_browser->getChildrenByTagName('name') ) {
114             $self->browser()->name( $ie_name->findvalue('text()') );
115             }
116             foreach my $ie_value ( $ie_browser->getChildrenByTagName('version') ) {
117             $self->browser()->version( $ie_value->findvalue('text()') );
118             }
119             }
120             return;
121             }
122              
123             sub _xml_pages {
124             my ( $self, $ie_log ) = @_;
125             foreach my $ie_pages ( $ie_log->getChildrenByTagName('pages') ) {
126             my @pages;
127             foreach my $ie_page ( $ie_pages->getChildrenByTagName('page') ) {
128             my $page = Archive::Har::Page->new();
129             foreach my $ie_id ( $ie_page->getChildrenByTagName('id') ) {
130             $page->id( $ie_id->findvalue('text()') );
131             }
132             foreach my $ie_title ( $ie_page->getChildrenByTagName('title') ) {
133             $page->title( $ie_title->findvalue('text()') );
134             }
135             foreach my $ie_started (
136             $ie_page->getChildrenByTagName('startedDateTime') )
137             {
138             $page->started_date_time( $ie_started->findvalue('text()') );
139             }
140             my $page_timings = Archive::Har::Page::PageTimings->new();
141             foreach
142             my $ie_timings ( $ie_page->getChildrenByTagName('pageTimings') )
143             {
144             foreach my $ie_content (
145             $ie_timings->getChildrenByTagName('onContentLoad') )
146             {
147             $page_timings->on_content_load(
148             $ie_content->findvalue('text()') );
149             }
150             foreach
151             my $ie_load ( $ie_timings->getChildrenByTagName('onLoad') )
152             {
153             $page_timings->on_load( $ie_load->findvalue('text()') );
154             }
155             $page->page_timings($page_timings);
156             }
157             push @pages, $page;
158             }
159             $self->pages( \@pages );
160             }
161             return;
162             }
163              
164             sub _xml_cookies {
165             my ( $self, $ie_object, $object ) = @_;
166             foreach my $ie_cookies ( $ie_object->getChildrenByTagName('cookies') ) {
167             my @cookies;
168             foreach my $ie_cookie ( $ie_cookies->getChildrenByTagName('cookie') ) {
169             my $cookie = Archive::Har::Entry::Cookie->new();
170             foreach my $ie_name ( $ie_cookie->getChildrenByTagName('name') ) {
171             $cookie->name( $ie_name->findvalue('text()') );
172             }
173             foreach my $ie_value ( $ie_cookie->getChildrenByTagName('value') ) {
174             $cookie->value( $ie_value->findvalue('text()') );
175             }
176             push @cookies, $cookie;
177             }
178             $object->cookies( \@cookies );
179             }
180             return;
181             }
182              
183             sub _xml_headers {
184             my ( $self, $ie_object, $object ) = @_;
185             foreach my $ie_headers ( $ie_object->getChildrenByTagName('headers') ) {
186             my @headers;
187             foreach my $ie_header ( $ie_headers->getChildrenByTagName('header') ) {
188             my $header = Archive::Har::Entry::Header->new();
189             foreach my $ie_name ( $ie_header->getChildrenByTagName('name') ) {
190             $header->name( $ie_name->findvalue('text()') );
191             }
192             foreach my $ie_value ( $ie_header->getChildrenByTagName('value') ) {
193             $header->value( $ie_value->findvalue('text()') );
194             }
195             push @headers, $header;
196             }
197             $object->headers( \@headers );
198             }
199             return;
200             }
201              
202             sub _xml_request {
203             my ( $self, $ie_entry, $entry ) = @_;
204             foreach my $ie_request ( $ie_entry->getChildrenByTagName('request') ) {
205             my $request = $entry->request();
206             foreach my $ie_method ( $ie_request->getChildrenByTagName('method') ) {
207             $request->method( $ie_method->findvalue('text()') );
208             }
209             foreach my $ie_url ( $ie_request->getChildrenByTagName('url') ) {
210             $request->url( $ie_url->findvalue('text()') );
211             }
212             foreach
213             my $ie_version ( $ie_request->getChildrenByTagName('httpVersion') )
214             {
215             $request->http_version( $ie_version->findvalue('text()') );
216             }
217             $self->_xml_cookies( $ie_request, $request );
218             $self->_xml_headers( $ie_request, $request );
219             foreach my $ie_query_string (
220             $ie_request->getChildrenByTagName('queryString') )
221             {
222             my @query_strings;
223             foreach
224             my $ie_param ( $ie_query_string->getChildrenByTagName('param') )
225             {
226             my $query_string =
227             Archive::Har::Entry::Request::QueryString->new();
228             foreach my $ie_name ( $ie_param->getChildrenByTagName('name') )
229             {
230             $query_string->name( $ie_name->findvalue('text()') );
231             }
232             foreach
233             my $ie_value ( $ie_param->getChildrenByTagName('value') )
234             {
235             $query_string->value( $ie_value->findvalue('text()') );
236             }
237             push @query_strings, $query_string;
238             }
239             $request->query_string( \@query_strings );
240             }
241             foreach
242             my $ie_post_data ( $ie_request->getChildrenByTagName('postData') )
243             {
244             my $post_data = Archive::Har::Entry::Request::PostData->new();
245             foreach my $ie_mime_type (
246             $ie_post_data->getChildrenByTagName('mimeType') )
247             {
248             $post_data->mime_type( $ie_mime_type->findvalue('text()') );
249             }
250             foreach my $ie_text ( $ie_post_data->getChildrenByTagName('text') )
251             {
252             $post_data->text( $ie_text->findvalue('text()') );
253             }
254             $request->post_data($post_data);
255             }
256             foreach my $ie_headers_size (
257             $ie_request->getChildrenByTagName('headersSize') )
258             {
259             $request->headers_size( $ie_headers_size->findvalue('text()') );
260             }
261             foreach
262             my $ie_body_size ( $ie_request->getChildrenByTagName('bodySize') )
263             {
264             $request->body_size( $ie_body_size->findvalue('text()') );
265             }
266             $entry->request($request);
267             }
268             return;
269             }
270              
271             sub _xml_response {
272             my ( $self, $ie_entry, $entry ) = @_;
273             foreach my $ie_response ( $ie_entry->getChildrenByTagName('response') ) {
274             my $response = $entry->response();
275             foreach my $ie_status ( $ie_response->getChildrenByTagName('status') ) {
276             $response->status( $ie_status->findvalue('text()') );
277             }
278             foreach my $ie_status_text (
279             $ie_response->getChildrenByTagName('statusText') )
280             {
281             $response->status_text( $ie_status_text->findvalue('text()') );
282             }
283             foreach
284             my $ie_version ( $ie_response->getChildrenByTagName('httpVersion') )
285             {
286             $response->http_version( $ie_version->findvalue('text()') );
287             }
288             $self->_xml_cookies( $ie_response, $response );
289             $self->_xml_headers( $ie_response, $response );
290             foreach my $ie_content ( $ie_response->getChildrenByTagName('content') )
291             {
292             my $content = Archive::Har::Entry::Response::Content->new();
293             foreach
294             my $ie_mime_type ( $ie_content->getChildrenByTagName('mimeType') )
295             {
296             $content->mime_type( $ie_mime_type->findvalue('text()') );
297             }
298             foreach my $ie_text ( $ie_content->getChildrenByTagName('text') ) {
299             $content->text( $ie_text->findvalue('text()') );
300             }
301             foreach my $ie_size ( $ie_content->getChildrenByTagName('size') ) {
302             $content->size( $ie_size->findvalue('text()') );
303             }
304             $response->content($content);
305             }
306             foreach my $ie_redirect_url (
307             $ie_response->getChildrenByTagName('redirectionURL') )
308             {
309             $response->redirect_url( $ie_redirect_url->findvalue('text()') );
310             }
311             foreach my $ie_headers_size (
312             $ie_response->getChildrenByTagName('headersSize') )
313             {
314             $response->headers_size( $ie_headers_size->findvalue('text()') );
315             }
316             foreach
317             my $ie_body_size ( $ie_response->getChildrenByTagName('bodySize') )
318             {
319             $response->body_size( $ie_body_size->findvalue('text()') );
320             }
321             $entry->response($response);
322             }
323             return;
324             }
325              
326             sub _xml_entries {
327             my ( $self, $ie_log ) = @_;
328             foreach my $ie_entries ( $ie_log->getChildrenByTagName('entries') ) {
329             my @entries;
330             foreach my $ie_entry ( $ie_entries->getChildrenByTagName('entry') ) {
331             my $entry = Archive::Har::Entry->new();
332             foreach
333             my $ie_pageref ( $ie_entry->getChildrenByTagName('pageref') )
334             {
335             $entry->pageref( $ie_pageref->findvalue('text()') );
336             }
337             foreach my $ie_started (
338             $ie_entry->getChildrenByTagName('startedDateTime') )
339             {
340             $entry->started_date_time( $ie_started->findvalue('text()') );
341             }
342             foreach
343             my $ie_timings ( $ie_entry->getChildrenByTagName('timings') )
344             {
345             my $timings = Archive::Har::Entry::Timings->new();
346             foreach
347             my $ie_send ( $ie_timings->getChildrenByTagName('send') )
348             {
349             $timings->send( $ie_send->findvalue('text()') );
350             }
351             foreach
352             my $ie_wait ( $ie_timings->getChildrenByTagName('wait') )
353             {
354             $timings->wait( $ie_wait->findvalue('text()') );
355             }
356             foreach my $ie_receive (
357             $ie_timings->getChildrenByTagName('receive') )
358             {
359             $timings->receive( $ie_receive->findvalue('text()') );
360             }
361             $entry->timings($timings);
362             }
363             $self->_xml_request( $ie_entry, $entry );
364             $self->_xml_response( $ie_entry, $entry );
365             push @entries, $entry;
366             }
367             $self->entries( \@entries );
368             }
369             return;
370             }
371              
372             sub xml {
373             my ( $self, $xml ) = @_;
374             my $parser = XML::LibXML->new();
375             my $ie_dom = $parser->parse_string($xml);
376             my $ie_log = $ie_dom->documentElement();
377             $self->_init();
378             foreach my $ie_version ( $ie_log->getChildrenByTagName('version') ) {
379             $self->version( $ie_version->findvalue('text()') );
380             }
381             $self->_xml_creator($ie_log);
382             $self->_xml_browser($ie_log);
383             $self->_xml_pages($ie_log);
384             $self->_xml_entries($ie_log);
385             return;
386             }
387              
388             sub version {
389             my ( $self, $new ) = @_;
390             my $old = $self->{log}->{version};
391             if ( @_ > 1 ) {
392             $self->{log}->{version} = $new;
393             }
394             if ( defined $old ) {
395             return $old;
396             }
397             else {
398             return '1.1';
399             }
400             }
401              
402             sub creator {
403             my ( $self, $new ) = @_;
404             my $old = $self->{log}->{creator};
405             if ( @_ > 1 ) {
406             $self->{log}->{creator} = $new;
407             }
408             return $old;
409             }
410              
411             sub browser {
412             my ( $self, $new ) = @_;
413             my $old = $self->{log}->{browser};
414             if ( @_ > 1 ) {
415             $self->{log}->{browser} = $new;
416             }
417             return $old;
418             }
419              
420             sub pages {
421             my ( $self, $new ) = @_;
422             my $old = $self->{log}->{pages};
423             if ( @_ > 1 ) {
424             if ( defined $new ) {
425             $self->{log}->{pages} = [];
426             my $page_count = 0;
427             foreach my $page ( @{$new} ) {
428             if ( !defined $page->{id} ) {
429             $page->{id} = 'page_' . $page_count;
430             }
431             push @{ $self->{log}->{pages} }, Archive::Har::Page->new($page);
432             $page_count += 1;
433             }
434             }
435             }
436             if ( defined $old ) {
437             return @{$old};
438             }
439             else {
440             return ();
441             }
442             }
443              
444             sub entries {
445             my ( $self, $entries ) = @_;
446             my $old = $self->{log}->{entries} || [];
447             if ( @_ > 1 ) {
448             $self->{log}->{entries} = [];
449             foreach my $entry ( @{$entries} ) {
450             push @{ $self->{log}->{entries} }, Archive::Har::Entry->new($entry);
451             }
452             }
453             return @{$old};
454             }
455              
456             sub comment {
457             my ( $self, $comment ) = @_;
458             my $old = $self->{log}->{comment};
459             if ( @_ > 1 ) {
460             $self->{log}->{comment} = $comment;
461             }
462             return $old;
463             }
464              
465             sub TO_JSON {
466             my ($self) = @_;
467             my $json = {};
468             $json->{version} = $self->version();
469             $json->{creator} = $self->creator();
470             if ( defined $self->browser() ) {
471             $json->{browser} = $self->browser();
472             }
473             if ( defined $self->pages() ) {
474             $json->{pages} = [ $self->pages() ];
475             }
476             $json->{entries} = [ $self->entries() ];
477             if ( defined $self->comment() ) {
478             $json->{comment} = $self->comment();
479             }
480             return { log => $json };
481             }
482              
483             1; # End of Archive::Har
484             __END__