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

Dear Monks,

I'm trying to send a GET request to localhost in an attempt to fetch a perl script in my Apache cgi-bin directory.

Here is what I have for the following variables:

my $host = 'localhost'; my $path = '/cgi-bin/second.pl'; my $port = 80;

If I use the short form of IO::Socket::INET->new() and create a socket like this:

my $CONN = IO::Socket::INET->new("$host:$port") or die "Couldn't connect: $!";

I am able to send a request:

my $req = "GET $path HTTP/1.0 $CRLF$CRLF"; $CONN->syswrite($req);

...and then I can read the header that the server sends back just fine:

$/ = CRLF . CRLF; #To read the whole header as one 'line' binmode $CONN; #Turn off \n conversion for getline() in next line my $header = $CONN->getline; $header =~ s/$CRLF/\n/g; say $header; --output:-- HTTP/1.1 200 OK Date: Sun, 21 Feb 2010 12:28:24 GMT Server: Apache/2.2.4 (Unix) mod_ssl/2.2.4 OpenSSL/0.9.7l DAV/2 PHP/5.2 +.3 mod_python/3.3.1 Python/2.4.4 Content-Length: 294 Connection: close Content-Type: text/html

However, if I keep everything the same, and I try to create the socket using the long format:

my $CONN = IO::Socket::INET->new( Peerhost => $host, Peerport => 'http(80)', ) or die "Couldn't connect: $!";

I get the following errors:

Use of uninitialized value $header in substitution (s///) at 4perl.pl +line 55. Use of uninitialized value $header in say at 4perl.pl line 56.

I also tried using just 80 for the Peerport, and I get the same result. Can anyone tell me why I am unable to retrieve the header using the long format for IO::Socket::INET->new()?

Thanks

Here's the full program:

use strict; use warnings; use 5.010; use IO::Socket qw{ :DEFAULT :crlf }; my $host = 'localhost'; my $path = '/cgi-bin/second.pl'; my $port = 80; =pod my $CONN = IO::Socket::INET->new("$host:$port") or die "Couldn't connect: $!"; =cut my $CONN = IO::Socket::INET->new( Peerhost => $host, Peerport => 'http(80)', ) or die "Couldn't connect: $!"; my $req = "GET $path HTTP/1.0 $CRLF$CRLF"; $CONN->syswrite($req); $/ = CRLF . CRLF; #To read whole header as one 'line' binmode $CONN; #turn off \n conversion for getline() below my $header = $CONN->getline; $header =~ s/$CRLF/\n/g; say $header; $CONN->close;

Replies are listed 'Best First'.
Re: IO::Socket::INET->new(): short form v. long form
by BrowserUk (Patriarch) on Feb 21, 2010 at 13:15 UTC

    Change Peerhost & Peerport to PeerHost & PeerPort and it'll work.

    It'd be kinda nice if the module reported failure for the connect attempt though.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: IO::Socket::INET->new(): short form v. long form
by Anonymous Monk on Feb 21, 2010 at 13:07 UTC
    you are using Peerhost and Peerport, which are not %options members, it should have been PeerHost and PeerAddr respectively, since the previous two are just some of the methods that IO::Socket::INET provides..
      PeerHost and PeerAddr are the same thing. I think you must have meant PeerHost and PeerPort.
Re: IO::Socket::INET->new(): short form v. long form
by 7stud (Deacon) on Feb 21, 2010 at 15:36 UTC

    Arrrgh. What a blunder....yet the long form for IO::Socket::INET->new() still won't work!

    Edit: Ok, I got the long form to work with PeerPort => 80, but it doesn't work for me with PeerPort => 'http(80)'.

    It'd be kinda nice if the module reported failure for the connect attempt though.

    Yes. At first I assumed the connection had failed, but then I realized my die() didn't execute.

    Edit2: lol. The combined form for PeerPort works for me if I add a space between 'http' and the port number:

    PeerPort => 'http (80)',

    And to make sure it was really working, i.e. looking up the port number for the specified service, 'http', and if not found then using the port number in parentheses, I tried this:

    PeerPort => 'abcxyz (80)',

    and I was able to successfully make a connection and get a response.