DevIo.pm: allow tcp/websocket path and header-extensions (Forum #109910)

git-svn-id: https://svn.fhem.de/fhem/trunk/fhem@22113 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
rudolfkoenig 2020-06-04 12:23:09 +00:00
parent 6fbf050eba
commit d9484b6548

View File

@ -453,9 +453,9 @@ DevIo_OpenDev($$$;$)
return &$doCb(""); return &$doCb("");
} }
} elsif($dev =~ m/^(ws:|wss:)?(.+):([0-9]+)$/) {# TCP (host:port) or websocket } elsif($dev =~ m/^(ws:|wss:)?([^:]+):([0-9]+)(.*?)$/) {# TCP or websocket
my ($proto, $host, $port) = ($1 ? $1 : "", $2, $3); my ($proto, $host, $port, $path) = ($1 ? $1 : "", $2, $3, $4);
$dev = "$host:$port"; $dev = "$host:$port";
if($proto eq "wss:") { if($proto eq "wss:") {
$hash->{SSL} = 1; $hash->{SSL} = 1;
@ -465,6 +465,8 @@ DevIo_OpenDev($$$;$)
require MIME::Base64; require MIME::Base64;
return &$doCb('websocket is only supported with callback') if(!$callback); return &$doCb('websocket is only supported with callback') if(!$callback);
} }
$path = "/" if(!defined($path) || $path eq "");
Log 1, "P:>$path<";
# This part is called every time the timeout (5sec) is expired _OR_ # This part is called every time the timeout (5sec) is expired _OR_
@ -507,22 +509,32 @@ DevIo_OpenDev($$$;$)
if($callback) { # reuse the nonblocking connect from HttpUtils. if($callback) { # reuse the nonblocking connect from HttpUtils.
use HttpUtils; use HttpUtils;
my %header = ();
if($proto eq "ws:") {
%header = (
"Connection" => "Upgrade",
"Upgrade" => "websocket",
"Sec-WebSocket-Key"=>encode_base64(pack("H*",createUniqueId()),""),
"Sec-WebSocket-Version" => 13
);
}
map { $header{$_} = $hash->{header}{$_} } keys %{$hash->{header}}
if($hash->{header});
my $err = HttpUtils_Connect({ # Nonblocking my $err = HttpUtils_Connect({ # Nonblocking
timeout => $timeout, timeout => $timeout,
url => $hash->{SSL} ? "https://$dev/" : "http://$dev/", url => $hash->{SSL} ? "https://$dev$path" : "http://$dev$path",
NAME => $hash->{NAME}, NAME => $hash->{NAME},
sslargs => $hash->{sslargs} ? $hash->{sslargs} : {}, sslargs => $hash->{sslargs} ? $hash->{sslargs} : {},
noConn2 => $proto eq "ws:" ? 0 : 1, noConn2 => $proto eq "ws:" ? 0 : 1,
keepalive=>$proto eq "ws:" ? 1 : 0, keepalive=>$proto eq "ws:" ? 1 : 0,
httpversion=>$proto eq "ws:" ? "1.1" : "1.0", httpversion=>$proto eq "ws:" ? "1.1" : "1.0",
header => $proto eq "ws:" ? { header => \%header,
"Connection" => "Upgrade",
"Upgrade" => "websocket",
"Sec-WebSocket-Key"=>encode_base64(pack("H*",createUniqueId()),""),
"Sec-WebSocket-Version" => 13
} : undef,
callback=> sub() { callback=> sub() {
my ($h, $err, undef) = @_; my ($h, $err, undef) = @_;
$err = "HTTP CODE $h->{code}"
if($proto eq "ws:" && !$err && $h->{code} != 101);
&$doTcpTail($err ? undef : $h->{conn}); &$doTcpTail($err ? undef : $h->{conn});
return &$doCb($err ? $err : &$doTailWork()); return &$doCb($err ? $err : &$doTailWork());
} }