PHP - 支持流加密的服务器切断字节

问题描述 投票:0回答:1

我用 PHP 制作了一个 WebSocket 服务器,并添加了向服务器添加 SSL/TLS 的功能。现在我使用stream_socket_enable_crypto启用了加密,一切正常。我读取数据并解密。只是 HTTP 请求有点奇怪:

客户端发送:

GET / HTTP/1.1
Host: example.com:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:120.0) Gecko/20100101 Firefox/120.0
Accept: */*
...

服务器接收:

 HTTP/1.1
Host: example.com:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:120.0) Gecko/20100101 Firefox/120.0
Accept: */*
...

我的问题是:丢失字节的原因是什么?我该怎么做才能取回这些字节?

我使用 PHP 8.2

服务器:

终端:

openssl genrsa -out wss.key 2048 && openssl req -key wss.key -new -x509 -days 365 -out wss.crt

PHP:

error_reporting(E_ALL);
ini_set("display_errors", "1");

if(ob_get_level() == 0) ob_start();

$server = stream_socket_server("tcp://example.com:8080", $errno, $errstr, STREAM_SERVER_BIND | STREAM_SERVER_LISTEN);

stream_context_set_option($server, ["ssl" => [
    "local_cert" => __DIR__."/wss.crt",
    "local_pk" => __DIR__."/wss.key",
    "disable_compression" => true,
    "verify_peer" => false,
    "verify_peer_name" => false,
    "allow_self_signed" => true
]]);

$done = false;
while(!$done) {
    $sockets = ["server" => $server];

    if(stream_select($sockets, $w, $e, 0, 20) === false)
        show("ERROR");

    if(in_array($server, $sockets)) {
        $client = stream_socket_accept($server);
        $sockets[] = $client;
        stream_socket_enable_crypto($client, true, STREAM_CRYPTO_METHOD_TLS_SERVER);
    }

    foreach($sockets as $client) {
        if(!in_array($client, $sockets))
            continue;

        show(fread($client, 100));

        fclose($client);
        $done = true;
        show("EXIT");
    }
}

function show(...$data) {
    var_dump($data);
    @ob_flush();
    flush();
}

客户:

JS:

url = "ws://example.com:8080";
socket = new WebSocket(url);
setTimeout(() => {
    socket.close();
    socket = new WebSocket(url);
}, 1000);

更改

example.com:8080
与您的主机和端口

详细代码请查看PHPWS

php websocket stream php-stream-wrappers
1个回答
1
投票

我现在知道这个问题了。 TCP paylaod 在

00 00
之后开始,在 HTTP 中开始
GET /
,在 TLS 中开始
TLS headers
17 03 03 03 15
以及 TLS 数据类型(应用程序数据
23
)、TLS 版本 (1.2
03 03
)和有效负载长度 (789
03 15
)

在 PHP 中,

stream_socket_enable_crypto
之后,第一个包被读取为 TLS,前 5 个字节被读取为 TLS 标头,失败后,因为它是 HTTP,所以在有效负载中丢失了这 5 个字节。

© www.soinside.com 2019 - 2024. All rights reserved.