php - PHP WebSocket 服务器无法访问 Origin 和 Referrer 标头
问题描述
我有一个简单的 PHP websocket 服务器
这是完整的代码:https ://gist.github.com/hack4mer/e40094001d16c75fe5ae8347ebffccb7
while (true) {
$changed = $clients;
socket_select($changed, $null, $null, 0, 10);
//check for new socket
if (in_array($socket, $changed)) {
$socket_new = socket_accept($socket); //accpet new socket
$clients[] = $socket_new; //add socket to client array
//THIS DOES NOT WORK
print_r($_SERVER);
die();
}
在浏览器的网络选项卡中,我可以确认以下请求:
Request URL: ws://localhost:12345/
Provisional headers are shown
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,hi;q=0.8,ms;q=0.7
Cache-Control: no-cache
Connection: Upgrade
Host: localhost:12345
Origin: http://localhost
但是我无法在我的脚本中访问这些请求标头。
我的目标是将 WebSocket 的访问限制在少数主机上
解决方案
我通过在握手之前进行标头检查解决了这个问题。
完整代码:https ://gist.github.com/hack4mer/e40094001d16c75fe5ae8347ebffccb7
function perform_handshaking($receved_header,$client_conn, $host, $port)
{
$headers = array();
$lines = preg_split("/\r\n/", $receved_header);
foreach($lines as $line)
{
$line = chop($line);
if(preg_match('/\A(\S+): (.*)\z/', $line, $matches))
{
$headers[$matches[1]] = $matches[2];
}
}
//HEADERS AVAILABLE HERE -> $headers
$secKey = $headers['Sec-WebSocket-Key'];
$secAccept = base64_encode(pack('H*', sha1($secKey . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')));
//hand shaking header
$upgrade = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" .
"Upgrade: websocket\r\n" .
"Connection: Upgrade\r\n" .
"WebSocket-Origin: $host\r\n" .
"WebSocket-Location: ws://$host:$port/demo/shout.php\r\n".
"Sec-WebSocket-Accept:$secAccept\r\n\r\n";
socket_write($client_conn,$upgrade,strlen($upgrade));
}
推荐阅读
- python - 每次用户再次询问时如何更改响应?
- c - C - 'long long 类型的索引 13 超出范围
- javascript - 使用钩子在 Reactjs 中创建一个动态占位符
- reactjs - 带有语义-ui-react 的单选按钮的自定义钩子
- java - Java 的 DecimalFormat 将不正确的十进制数解析为整数
- react-native - 如何解决 TypeError: undefined is not an object (evaluate 'rss.items[i].title')?
- c# - Selemium 在网站上找不到元素
- python - Ecmwf api 作业期间出现隧道错误
- java - Kafka Streams多个活页夹配置不起作用
- node.js - 如何通过 web3 使用 privateKey 登录以太坊账户?