Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"

using Net::Telnet to test Apache

by meonkeys (Chaplain)
on Nov 13, 2000 at 12:22 UTC ( #41276=perlquestion: print w/replies, xml ) Need Help??

meonkeys has asked for the wisdom of the Perl Monks concerning the following question:

This is my weak attempt at automating a mundane Apache test, trying to telnet in to port 80 and doing a HTTP GET. It's probably not what Net::Telnet was meant to do. Could anyone offer hints on ways to do this better (eg. so it works)?
#!/usr/bin/perl -w use strict; use Time::HiRes qw( time tv_interval ); use Net::Telnet (); my $hosts = join ' ', @ARGV; unless ($hosts){ die "Usage: ruffbench <host> [<host2> <host3> ...]\n"; } my $port = '80'; my $t = new Net::Telnet; my $get = "GET / HTTP/1.0\n\n"; my $output; foreach my $host ($hosts) { print "Connecting to $host. Starting timer.\n"; print $t->dump_log(*STDERR); # no debugging is seen! :| my $start = [ time() ]; $t->open(Host=>$host, Port=>$port); print "Connected to $host. Sending request...\n"; print $t->waitfor(String=>"HTTP", Timeout=>5); $t->print($get); print $t->waitfor(String=>"Content-Type", Timeout=>5); my $end = [ time() ]; $t->close; print "Connection closed. Timer stopped.\n\n"; print "Time for simple GET from $host: " . tv_interval($start, $end) . " seconds.\n"; }

I'm not sure why, but I get no debugging info, even if I swap out *STDERR with, say, "dump.log".


Replies are listed 'Best First'.
Re: using Net::Telnet to test Apache
by Fastolfe (Vicar) on Nov 13, 2000 at 18:40 UTC
    Many people assume "telnet" is a simple raw network connection, and is thus suitable anytime you want to connect and test some TCP port. This really isn't the case. There is, in fact, a "telnet protocol" that describes all sorts of terminal negotiation. No doubt, this is what Net::Telnet was built for, so no, I don't expect this was what you were wanting.

    Try using a simple IO::Socket to set up a TCP connection to your web server. You can then freely read and write to it as you need to.

    my $s = new IO::Socket::INET ("") or die "Couldn't connect: $!"; print $s "GET / HTTP/1.0\n\n"; if (<$s> =~ /HTTP\S+ ([345].*)/) { die "Error: $1"; } ...
    An alternative (as another poster mentioned) is to use the LWP modules, which offer a complete HTTP client library.
    use LWP::Simple; # or you could do more advanced stuff my $results = get(""); if (!defined($results)) { die "Error!"; } ...
Re: using Net::Telnet to test Apache
by zejames (Hermit) on Nov 13, 2000 at 14:37 UTC
    perhaps could you use the LWP module, to check if your server is all right...



Re: using Net::Telnet to test Apache
by ColtsFoot (Chaplain) on Nov 13, 2000 at 12:58 UTC
    What string do you get returned when you issue the following command
    telent yourhost.dom 80
    I suspect that as you are waiting for a string "HTTP" that this is the reason
    your request is timing out
      Yes... you are exactly right. after commenting out the line
      print $t->waitfor(String=>"HTTP", Timeout=>5 );

      It works, and I can now get a debugging log. Here's what I see from a normal Telnet...
      [meonkeys@serendipity scripts]$ telnet 80 Trying Connected to Escape character is '^]'.

      Thank you kindly for your help.
Re: using Net::Telnet to test Apache
by meonkeys (Chaplain) on Nov 14, 2000 at 03:45 UTC
    I've seen the advice n times (where n > 3) to use the LWP libs instead of Net::Telnet. The problem is, does not specify which http daemon actually serves the page. It looks like IO::Socket::INET is the next best bet, this module lets one specify hostnames. Anyway, here's a working version of the originally posted code:
    #!/usr/bin/perl use strict; use Time::HiRes qw( time tv_interval ); use Net::Telnet (); $0 = 'ruffbench'; unless (@ARGV){ die "Usage: $0 <host> [<host2> <host3> ...]\n"; } my $port = '80'; my $t = new Net::Telnet; my $get = "GET / HTTP/1.0\n\n"; my %time; foreach my $host (@ARGV) { print "$0: Connecting to $host. Starting timer.\n"; my $start = [ time() ]; $t->open(Host=>$host, Port=>$port); print "$0: Connected to $host. Sending request...\n"; $t->print($get); print $t->waitfor(String=>"Content-Type", Timeout=>5 ); my $end = [ time() ]; $t->close; print "\n$0: Connection closed. Timer stopped.\n\n"; $time{$host} = tv_interval($start, $end); } print "$0: Summary of results:\n"; foreach my $host (@ARGV) { printf "%9s: %10s ... %2.2f seconds\n", $0, $host, $time{$host}; }
      I'm not following. Presumably the only httpd daemon is the one listening on port 80. If you want a different daemon listening on a different port, LWP can handle just as easily.
        I'm talking about different hosts. Sorry for not being clearer. What I meant is that a URL does not necessarily specify which host a http daemon is active on. For instance, you could have 20 boxes that all correspond to one URL-- for example--that alternately serve pages to balance the load. I'm sure you already know all this.

        So, now the question is, what is the best way to test how each individual host's http daemon is doing? The only way I know how is by telnetting into that host's port 80 and doing a HTTP get. IO::Socket::INET sounds interesting, although I don't quite understand how it differs and I haven't successfully implemented it yet.

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://41276]
Approved by root
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (4)
As of 2021-09-28 08:37 GMT
Find Nodes?
    Voting Booth?

    No recent polls found