mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-05-04 22:19:38 +00:00
DevIo.pm: Mask websocket replies (Forum #109910)
git-svn-id: https://svn.fhem.de/fhem/trunk/fhem@22100 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
31405959e7
commit
85b9f3c13e
@ -125,6 +125,33 @@ DevIo_TimeoutRead($$;$$)
|
|||||||
return $answer;
|
return $answer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub
|
||||||
|
DevIo_MaskWS($$)
|
||||||
|
{
|
||||||
|
my ($opcode,$msg) = @_;
|
||||||
|
$opcode = pack("C",$opcode|0x80);
|
||||||
|
|
||||||
|
my $len = length($msg);
|
||||||
|
my $lb;
|
||||||
|
if($len < 126) {
|
||||||
|
$lb = chr(0x80+$len);
|
||||||
|
} else {
|
||||||
|
if ($len < 65536) {
|
||||||
|
$lb = chr(0x8E) . pack('n', $len);
|
||||||
|
} else {
|
||||||
|
$lb = chr(0x8F) . chr(0x00) . chr(0x00) .
|
||||||
|
chr(0x00) . chr(0x00) . pack('N', $len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
my $mask = pack("L",rand(2**32));
|
||||||
|
my @m = unpack("C*", $mask);
|
||||||
|
my $idx = 0;
|
||||||
|
$msg = pack("C*", map { $_ ^ $m[$idx++ % 4] } unpack("C*", $msg));
|
||||||
|
return $opcode.$lb.$mask.$msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
sub
|
sub
|
||||||
DevIo_DecodeWS($$)
|
DevIo_DecodeWS($$)
|
||||||
{
|
{
|
||||||
@ -141,19 +168,6 @@ DevIo_DecodeWS($$)
|
|||||||
my $len = (ord(substr($data,1,1)) & 0x7F);
|
my $len = (ord(substr($data,1,1)) & 0x7F);
|
||||||
my $i = 2;
|
my $i = 2;
|
||||||
|
|
||||||
# $op: 0=>Continuation, 1=>Text, 2=>Binary, 8=>Close, 9=>Ping, 10=>Pong
|
|
||||||
Log3 $hash, 5, "Websocket msg: OP:$op LEN:$len MASK:$mask FIN:$fin";
|
|
||||||
if($op == 8) { # Close, Normal, empty mask. #104718
|
|
||||||
syswrite($hash->{TCPDev}, pack("CCn",0x88,0x2,1000));
|
|
||||||
DevIo_CloseDev($hash);
|
|
||||||
return undef;
|
|
||||||
|
|
||||||
} elsif($op == 9) { # Ping
|
|
||||||
syswrite($hash->{TCPDev}, chr(0x8A).chr(0)); # Pong
|
|
||||||
$hash->{".WSBUF"} = substr($data, 2);
|
|
||||||
return DevIo_DecodeWS($hash, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
if( $len == 126 ) {
|
if( $len == 126 ) {
|
||||||
return "" if(length($data) < 4);
|
return "" if(length($data) < 4);
|
||||||
$len = unpack('n', substr($data, $i, 2));
|
$len = unpack('n', substr($data, $i, 2));
|
||||||
@ -178,6 +192,20 @@ DevIo_DecodeWS($$)
|
|||||||
my $idx = 0;
|
my $idx = 0;
|
||||||
$data = pack("C*", map { $_ ^ $m[$idx++ % 4] } unpack("C*", $data));
|
$data = pack("C*", map { $_ ^ $m[$idx++ % 4] } unpack("C*", $data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# $op: 0=>Continuation, 1=>Text, 2=>Binary, 8=>Close, 9=>Ping, 10=>Pong
|
||||||
|
Log3 $hash, 5, "Websocket msg: OP:$op LEN:$len MASK:$mask FIN:$fin";
|
||||||
|
if($op == 8) { # Close, Normal, empty mask. #104718
|
||||||
|
syswrite($hash->{TCPDev}, DevIo_MaskWS(0x8,$data));
|
||||||
|
DevIo_CloseDev($hash);
|
||||||
|
return undef;
|
||||||
|
|
||||||
|
} elsif($op == 9) { # Ping
|
||||||
|
syswrite($hash->{TCPDev}, DevIo_MaskWS(0xA, $data)); # Pong
|
||||||
|
$hash->{".WSBUF"} = substr($data, 2);
|
||||||
|
return DevIo_DecodeWS($hash, "");
|
||||||
|
}
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,19 +226,7 @@ DevIo_SimpleWrite($$$;$)
|
|||||||
$hash->{USBDev}->write($msg);
|
$hash->{USBDev}->write($msg);
|
||||||
|
|
||||||
} elsif($hash->{TCPDev}) {
|
} elsif($hash->{TCPDev}) {
|
||||||
if($hash->{WEBSOCKET}) {
|
$msg = DevIo_MaskWS($hash->{binary} ? 0x2:0x1, $msg) if($hash->{WEBSOCKET});
|
||||||
my $len = length($msg);
|
|
||||||
if($len < 126) {
|
|
||||||
$msg = chr(0x81) . chr($len) . $msg;
|
|
||||||
} else {
|
|
||||||
if ($len < 65536) {
|
|
||||||
$msg = chr(0x81) . chr(0x7E) . pack('n', $len) . $msg;
|
|
||||||
} else {
|
|
||||||
$msg = chr(0x81) . chr(0x7F) . chr(0x00) . chr(0x00) .
|
|
||||||
chr(0x00) . chr(0x00) . pack('N', $len) . $msg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
syswrite($hash->{TCPDev}, $msg);
|
syswrite($hash->{TCPDev}, $msg);
|
||||||
|
|
||||||
} elsif($hash->{DIODev}) {
|
} elsif($hash->{DIODev}) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user