2017-03-01 25 views
3

使用perl从头开始创建一个简单的websocket服务器时,从Chrome指向它(通过使用echo test),得到错误Error during WebSocket handshake: Incorrect 'Sec-WebSocket-Accept' header value从零开始的简单websocket服务器不起作用

很确定为websocket握手返回的密钥是正确的。有任何想法吗?

use IO::Socket; 
use IO::Select; 
use Digest::SHA1 qw(sha1 sha1_hex sha1_base64); 


$servSock = IO::Socket::INET->new(Proto => 'tcp', 
           LocalPort => 8080, 
           Reuse  => 1, 
           Listen => 500 
    ) || die "failed to setup outsock [email protected]\n"; 
$s = IO::Select->new(); 
$s -> add ($servSock); 
my @readySocks; 
while (1) { 
    @readySocks = $s->can_read(5); 
    foreach $sock (@readySocks) { 
     if ($sock eq $servSock) 
     { 
      #print "inSock\n"; 
      $clientSock = $servSock->accept(); 
      setsockopt($clientSock, IPPROTO_TCP, TCP_NODELAY, 1); 
      $s->add ($clientSock); 
     } else 
     { 
     #print "outsock\n"; 
     $buff = ""; 
     $fromAddr = recv $sock, $buff, 1470, 0; 
     if (length($buff) <= 0) 
     { 
      $s->remove($sock); 
      close $sock; $numOfConns --; 
      next; 
     } 
     printf "recved %d bytes\n", length($buff); 
     if ($buff =~ /Sec-WebSocket-Key: (\S+)/) { 
      $str = $1; 
      print "key is $str|\n"; 
      my $str = sha1_base64($str . "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"); 
      send ($sock, qq{HTTP/1.1 101 Switching Protocols\r 
Connection: Upgrade\r 
Upgrade: websocket\r 
Sec-Websocket-Accept: $str\r 
\r\n}, 0); 
     } 
     } 
    } 
} 

注:我需要从头开始创建一个作为另一个项目的一部分。

更新

由于从@到的建议斯特芬 - 乌尔里希,改变它

send ($sock, qq{HTTP/1.1 101 Switching Protocols\r 
Connection: Upgrade\r 
Upgrade: websocket\r 
Sec-Websocket-Accept: $str\r 
\r\n}, 0); 

到(注意有现在$str$str=

send ($sock, qq{HTTP/1.1 101 Switching Protocols\r 
Connection: Upgrade\r 
Upgrade: websocket\r 
Sec-Websocket-Accept: $str=\r 
\r\n}, 0); 

使其工作。

回答

5

documentation of sha1_bas64

注意,base64编码字符串返回是不填充是4个字节的整数倍。如果您想要与其他base64编码的sha1摘要进行互操作,您可能需要将冗余字符串“=”附加到结果

并且如上所述添加'='代表您的代码缺失。

+0

非常感谢你steffen-ullrich,它现在可以工作! – packetie