File Coverage

blib/lib/Browsermob/Server.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 Browsermob::Server;
2             $Browsermob::Server::VERSION = '0.15';
3             # ABSTRACT: Perl client to control the Browsermob Proxy server
4 4     4   148912 use strict;
  4         6  
  4         126  
5 4     4   16 use warnings;
  4         5  
  4         75  
6 4     4   1896 use Moo;
  4         44351  
  4         21  
7 4     4   4744 use Carp;
  4         7  
  4         247  
8 4     4   1793 use JSON;
  4         29921  
  4         25  
9 4     4   2501 use LWP::UserAgent;
  4         110413  
  4         157  
10 4     4   2226 use IO::Socket::INET;
  4         61658  
  4         26  
11 4     4   3296 use Browsermob::Proxy;
  0            
  0            
12              
13              
14             has path => (
15             is => 'rw',
16             );
17              
18              
19             has server_addr => (
20             is => 'rw',
21             default => sub { 'localhost' }
22             );
23              
24              
25             has server_port => (
26             is => 'rw',
27             init_arg => 'port',
28             default => sub { 8080 }
29             );
30              
31             has _pid => (
32             is => 'rw',
33             init_arg => undef,
34             default => sub { '' }
35             );
36              
37             has ua => (
38             is => 'rw',
39             lazy => 1,
40             default => sub {
41             return LWP::UserAgent->new;
42             }
43             );
44              
45              
46             sub start {
47             my $self = shift;
48             die '"' . $self->path . '" is an invalid path' unless -f $self->path;
49              
50             defined ($self->_pid(fork)) or die "Error starting server: $!";
51             if ($self->_pid) {
52             # The parent knows about the child pid
53             die "Error starting server: $!" unless $self->_is_listening;
54             }
55             else {
56             # If I don't know the pid, then I'm the child and we should
57             # exec to replace ourselves with the proxy
58             my $cmd = 'sh ' . $self->path . ' -port ' . $self->server_port . ' 2>&1 > /dev/null';
59             exec($cmd);
60             }
61             }
62              
63              
64             sub stop {
65             my $self = shift;
66             kill('SIGKILL', $self->_pid) and waitpid($self->_pid, 0);
67             }
68              
69              
70             sub create_proxy {
71             my ($self, %args) = @_;
72              
73             my $proxy = Browsermob::Proxy->new(
74             server_addr => $self->server_addr,
75             server_port => $self->server_port,
76             %args
77             );
78              
79             return $proxy;
80             }
81              
82              
83             sub get_proxies {
84             my $self = shift;
85             my $ua = $self->ua;
86              
87             my $res = $ua->get('http://' . $self->server_addr . ':' . $self->server_port . '/proxy');
88             if ($res->is_success) {
89             my $list = from_json($res->decoded_content)->{proxyList};
90              
91             my @proxies = map {
92             $_->{port};
93             } @$list;
94              
95             return \@proxies;
96             }
97              
98             }
99              
100              
101             sub find_open_port {
102             my ($self, @range) = @_;
103             my $proxies = $self->get_proxies;
104              
105             my $count;
106             foreach (@range, @$proxies) {
107             $count->{$_}++;
108             }
109              
110             foreach (sort keys %$count) {
111             if ($count->{$_} == 1) {
112             return $_;
113             }
114             }
115             }
116              
117              
118             sub _is_listening {
119             my ($self, $timeout) = @_;
120             $timeout //= 30;
121              
122             my $sock = IO::Socket::INET->new(
123             PeerAddr => $self->server_addr,
124             PeerPort => $self->server_port,
125             Timeout => $timeout
126             );
127              
128             return $sock;
129             }
130              
131             1;
132              
133             __END__
134              
135             =pod
136              
137             =encoding UTF-8
138              
139             =head1 NAME
140              
141             Browsermob::Server - Perl client to control the Browsermob Proxy server
142              
143             =head1 VERSION
144              
145             version 0.15
146              
147             =head1 SYNOPSIS
148              
149             my $server = Browsermob::Server->new(
150             path => '/opt/browsermob-proxy-2.0-beta-9/bin/browsermob-proxy'
151             );
152             $server->start; # ignore if your server is already started
153              
154             my $proxy = $server->create_proxy;
155             my $port = $proxy->port;
156              
157             $proxy->new_har;
158              
159             # generate traffic across your port
160             `curl -x http://localhost:$port http://www.google.com > /dev/null 2>&1`;
161              
162             print Dumper $proxy->har;
163              
164             =head1 DESCRIPTION
165              
166             This class provides a way to control the Browsermob Proxy server
167             within Perl. There are only a few public methods for starting and
168             stopping the server. You also have the option of instantiating a
169             server object and pointing it towards an existing BMP server on
170             localhost, and just using it to avoid having to pass the server_port
171             arg when instantiating new proxies.
172              
173             =head1 ATTRIBUTES
174              
175             =head2 path
176              
177             The path to the browsermob_proxy binary. If you aren't planning to
178             call C<start>, this is optional.
179              
180             =head2 server_addr
181              
182             The address of the remote server where the Browsermob Proxy server is
183             running. This defaults to localhost.
184              
185             =head2 port
186              
187             The port on which the proxy server should run. This is not the port
188             that you should have other clients connect.
189              
190             =head1 METHODS
191              
192             =head2 start
193              
194             Start a browsermob proxy on C<port>. Starting the server does not create
195             any proxies.
196              
197             =head2 stop
198              
199             Stop the forked browsermob-proxy server. This does not work all the
200             time, although the server seems to get GC'd all on its own, even after
201             ignoring a C<SIGTERM>.
202              
203             =head2 create_proxy
204              
205             After starting the server, or connecting to an existing one, use
206             C<create_proxy> to get a proxy that you can use with your tests. No
207             proxies actually exist until you call create_proxy; starting the
208             server does not create a proxy.
209              
210             my $proxy = $bmp->create_proxy; # returns a Browsermob::Proxy object
211             my $proxy = $bmp->create_proxy(port => 1337);
212              
213             =head2 get_proxies
214              
215             Get a list of currently registered proxies.
216              
217             my $proxy_aref = $bmp->get_proxies->{proxyList};
218             print scalar @$proxy_aref;
219              
220             =head2 find_open_port
221              
222             Given a range of valid ports, finds the lowest unused port by
223             searching the proxyList.
224              
225             my $unused_port = $bmp->find_open_port;
226             my $proxy = $bmp->create_proxy(port => $unused_port);
227              
228             =head1 SEE ALSO
229              
230             Please see those modules/websites for more information related to this module.
231              
232             =over 4
233              
234             =item *
235              
236             L<Browsermob::Proxy|Browsermob::Proxy>
237              
238             =back
239              
240             =head1 BUGS
241              
242             Please report any bugs or feature requests on the bugtracker website
243             https://github.com/gempesaw/Browsermob-Proxy/issues
244              
245             When submitting a bug or request, please include a test-file or a
246             patch to an existing test-file that illustrates the bug or desired
247             feature.
248              
249             =head1 AUTHOR
250              
251             Daniel Gempesaw <gempesaw@gmail.com>
252              
253             =head1 COPYRIGHT AND LICENSE
254              
255             This software is copyright (c) 2014 by Daniel Gempesaw.
256              
257             This is free software; you can redistribute it and/or modify it under
258             the same terms as the Perl 5 programming language system itself.
259              
260             =cut