2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-04-21 20:06:18 +00:00
fhem-mirror/fhem/FHEM/HttpUtils.pm
rudolfkoenig 6d321a6553 HTTP/SSL added
git-svn-id: https://svn.fhem.de/fhem/trunk@1648 2b470e98-0d58-463d-a4d8-8e2adae1ed80
2012-06-25 06:54:01 +00:00

100 lines
2.4 KiB
Perl

##############################################
# $Id: HttpUtils.pm 1148 2011-12-28 19:21:19Z rudolfkoenig $
package main;
use strict;
use warnings;
use IO::Socket::INET;
##################
sub
urlEncode($) {
$_= $_[0];
s/([\x00-\x2F,\x3A-\x40,\x5B-\x60,\x7B-\xFF])/sprintf("%%%02x",ord($1))/eg;
return $_;
}
##################
# - if data (which is urlEncoded) is set, then a POST is performed, else a GET.
# - noshutdown must be set for e.g the Fritz!Box
sub
GetFileFromURL($@)
{
my ($url, $timeout, $data, $noshutdown) = @_;
$timeout = 4.0 if(!defined($timeout));
if($url !~ /^(http|https):\/\/([^:\/]+)(:\d+)?(\/.*)$/) {
Log 1, "GetFileFromURL $url: malformed or unsupported URL";
return undef;
}
my ($protocol,$host,$port,$path)= ($1,$2,$3,$4);
if(defined($port)) {
$port =~ s/^://;
} else {
$port = ($protocol eq "https" ? 443: 80);
}
$path= '/' unless defined($path);
my $conn;
if($protocol eq "https") {
eval "use IO::Socket::SSL";
Log 1, $@ if($@);
$conn = IO::Socket::SSL->new(PeerAddr => "$host:$port") if(!$@);
} else {
$conn = IO::Socket::INET->new(PeerAddr => "$host:$port");
}
if(!$conn) {
Log 1, "GetFileFromURL: Can't connect to $protocol://$host:$port\n";
undef $conn;
return undef;
}
$host =~ s/:.*//;
my $hdr = ($data ? "POST" : "GET")." $path HTTP/1.0\r\nHost: $host\r\n";
if(defined($data)) {
$hdr .= "Content-Length: ".length($data)."\r\n";
$hdr .= "Content-Type: application/x-www-form-urlencoded";
}
$hdr .= "\r\n\r\n";
syswrite $conn, $hdr;
syswrite $conn, $data if(defined($data));
shutdown $conn, 1 if(!$noshutdown);
my ($buf, $ret) = ("", "");
$conn->timeout($timeout);
for(;;) {
my ($rout, $rin) = ('', '');
vec($rin, $conn->fileno(), 1) = 1;
my $nfound = select($rout=$rin, undef, undef, $timeout);
if($nfound <= 0) {
Log 1, "GetFileFromURL: Select timeout/error: $!";
undef $conn;
return undef;
}
my $len = sysread($conn,$buf,65536);
last if(!defined($len) || $len <= 0);
$ret .= $buf;
}
$ret=~ s/(.*?)\r\n\r\n//s; # Not greedy: switch off the header.
Log 4, "GetFileFromURL: Got http://$host$path, length: ".length($ret);
undef $conn;
return $ret;
}
##################
# Compatibility mode
sub
GetHttpFile($$)
{
my ($host,$file) = @_;
return GetFileFromURL("http://$host$file");
}
1;