# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # # NAME # # HTTPcon - make HTTP connection. # # # # SYNOPSIS # # $stat = &HTTPcon(*F,'fubar.com:1234'); # # # # DESCRIIPTION # # This accepts a URL's host:port portion, and attempts to make the # # connection. If successful, we return 1 with F open to the TCP # # socket. If we fail, we return 0, and F may or may not be open. # # (Maybe we should close it.) # # # # TIMEOUTS # # I've added a timeout kludge: If $HTTPtimeout is nonzero, we will # # exit after that many seconds. This is drastic, but it seems to be # # the only solution to the hung-connect problem. This is mostly # # used in webcat, which is used as a subprocess by other programs. # # If you call "webcat -T15 ...", it will exit after 15 seconds if # # the connection can't be made, and you can go about your business. # # # # AUTHOR # # John Chambers # # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # $HTTPcontime = time; $HTTPcons = 0; # Count of connections. $HTTPalrm = 0; # Alarm needs to be handled. sub HTTPcon { local(*HTTPsock,$hp) = @_; local($a,$b,$c,$d); local(@addrs,$host,$port,$savsig,$t,$this,$that,$This,$That); $HTTPtimeout = 30 unless defined $HTTPtimeout; $W3trace = 0 unless defined $W3trace; if (($host,$port) = ($hp =~ m"^(.*):(\d+)$")) { print V "HTTPcon: host=\"$host\" port=\"$port\"\n" if $V>5; } else { $host = $hp; $port = 80; print V "HTTPcon: host=\"$host\" port=$port.\n" if $V>5; } $AF_INET = 2; $SOCK_STREAM = 1; $sockaddr = 'S n a4 x8'; ($name,$aliases,$proto) = getprotobyname('tcp'); ($name,$aliases,$port) = getservbyname($port,'tcp') unless $port =~ /^\d+$/; $thisaddr = "\0\0\0\0"; print "\n" if $W3trace; ($name,$aliases,$type,$len,@addrs) = gethostbyname($host); if (!@addrs) { $errmsg = "No address for \"$host\""; return 0; } $thataddr = $addrs[0]; $this = pack($sockaddr, $AF_INET, 0, $thisaddr); $that = pack($sockaddr, $AF_INET, $port, $thataddr); ($a,$b,$c,$d) = unpack('C4',$thisaddr); $This = "$a.$b.$c.$d:0"; ($a,$b,$c,$d) = unpack('C4',$thataddr); $That = "$a.$b.$c.$d:$port"; if (socket(HTTPsock,$AF_INET,$SOCK_STREAM,$proto)) { print V "HTTPcon: Got socket.\n" if $V>5; } else { print V "HTTPcon: Can't get socket ($!)\n" if $V>0; $exitstat = $!; return 0; } if (bind(HTTPsock,$this)) { $t = time - $HTTPcontime; print V "HTTPcon: Bind to \"$This\" succeeded in $t sec.\n" if $V>5; } else { $t = time - $HTTPcontime; print V "HTTPcon: Bind to \"$This\" failed in $t sec ($!)\n" if $V>2; $exitstat = $!; return 0; } ++$HTTPcons; $HTTPcontime = time; if ($HTTPtimeout > 0) { alarm $HTTPtimeout; $savsig = $SIG{ALRM}; $SIG{ALRM} = 'HTTPalarm'; print V "HTTPcon: Set alarm after $HTTPtimeout sec.\n" if $V>3; } print "\n" if $W3trace; print "HTTPcon: Connecting to \"$That\"\n" if $V>5; if (connect(HTTPsock,$that)) { $t = time - $HTTPcontime; print V "HTTPcon: Connect $HTTPcons to \"$That\" succeeded in $t sec.\n" if $V>5; print "\n" if $W3trace; if ($HTTPtimeout > 0) { alarm 0; $SIG{ALRM} = $savsig; print V "HTTPcon: Set alarm 0.\n" if $V>5; } } else { $t = time - $HTTPcontime; print "\n" if $W3trace; # exit -1; $errmsg = 'timeout'; } 1;