2017-03-01 48 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