iTranslated by AI
The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article
🕌
[PHP] Sending frames to an HTTP/2 server without TLS
I tried sending some frames to an HTTP/2 server written in Go without TLS.
Looking at the logs, it seems a plausible response was obtained.
> GODEBUG=http2debug=2,http1debug=2 go run main.go
Listening [0.0.0.0:8000]...
2024/07/05 12:40:42 h2c: attempting h2c with prior knowledge.
2024/07/05 12:40:42 http2: server connection from [::1]:58570 on 0xc0000fc000
2024/07/05 12:40:42 http2: Framer 0xc0001840e0: wrote SETTINGS len=30, settings: MAX_FRAME_SIZE=1048576, MAX_CONCURRENT_STREAMS=250, MAX_HEADER_LIST_SIZE=1048896, HEADER_TABLE_SIZE=4096, INITIAL_WINDOW_SIZE=1048576
2024/07/05 12:40:42 http2: Framer 0xc0001840e0: read SETTINGS len=0
2024/07/05 12:40:42 http2: server read frame SETTINGS len=0
2024/07/05 12:40:42 http2: Framer 0xc0001840e0: read SETTINGS flags=ACK len=0
2024/07/05 12:40:42 http2: server read frame SETTINGS flags=ACK len=0
2024/07/05 12:40:42 http2: Framer 0xc0001840e0: read HEADERS flags=END_STREAM|END_HEADERS stream=1 len=61
2024/07/05 12:40:42 http2: decoded hpack field header field ":method" = "GET"
2024/07/05 12:40:42 http2: decoded hpack field header field ":path" = "/"
2024/07/05 12:40:42 http2: decoded hpack field header field ":scheme" = "https"
2024/07/05 12:40:42 http2: decoded hpack field header field ":authority" = "nghttp2.org"
2024/07/05 12:40:42 http2: Framer 0xc0001840e0: wrote SETTINGS flags=ACK len=0
2024/07/05 12:40:42 http2: Framer 0xc0001840e0: wrote WINDOW_UPDATE len=4 (conn) incr=983041
2024/07/05 12:40:42 http2: server read frame HEADERS flags=END_STREAM|END_HEADERS stream=1 len=61
2024/07/05 12:40:42 http2: server connection error from [::1]:58570: connection error: FRAME_SIZE_ERROR
2024/07/05 12:40:42 http2: Framer 0xc0001840e0: wrote GOAWAY len=8 LastStreamID=1 ErrCode=FRAME_SIZE_ERROR Debug=""
2024/07/05 12:40:43 GOAWAY close timer fired; closing conn from [::1]:58570
Since all requests were sent in a single connect, the responses from multiple stages ended up being grouped together at the data event stage. Also, the response obtained can sometimes change when requesting multiple times.
php client.php
00001e0400000000000005001000000003000000fa000600100140000100001000000400100000
39
php client.php
00001e0400000000000005001000000003000000fa000600100140000100001000000400100000000000040100000000000004080000000000000f0001
61
client.php
<?php
require __DIR__ . '/vendor/autoload.php';
$uri = "tcp://localhost:8000";
$connector = new React\Socket\Connector();
$connector->connect($uri)->then(function (React\Socket\ConnectionInterface $connection) {
$connection->on('connection', function () use ($connection) {
echo "connection\r\n";
});
$connection->on('data', function ($chunk) use ($connection) {
echo bin2hex($chunk), PHP_EOL;
echo strlen($chunk), PHP_EOL;
$connection->end();
});
// https://qiita.com/0xfffffff7/items/0960527dca6de364daeb
//
// HTTP/2 Connection Preface
$connection->write("PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n");
// SETTINGS frame 0x04
$settings = "\x00\x00\x00".
"\x04".
"\x00".
"\x00\x00\x00\x00";
$connection->write($settings);
// ACK 0x04
$ack = "\x00\x00\x00".
"\x04".
"\x01".
"\x00\x00\x00\x00";
$connection->write($ack);
// HEADERS frame 0x01
$headers = "\x00\x00\x3d\x01\x05\x00\x00\x00\x01". // Header frame
"\x00". // Compression information
"\x07\x3a\x6d\x65\x74\x68\x6f\x64". // 7 :method
"\x03\x47\x45\x54". // 3 GET
"\x00". // Compression information
"\x05\x3a\x70\x61\x74\x68". // 5 :path
"\x01\x2f". // 1 /
"\x00". // Compression information
"\x07\x3a\x73\x63\x68\x65\x6d\x65". // 7 :scheme
"\x05\x68\x74\x74\x70\x73". // 5 https
"\x00". // Compression information
"\x0a\x3a\x61\x75\x74\x68\x6f\x72\x69\x74\x79". // 10 :authority
"\x0b\x6e\x67\x68\x74\x74\x70\x32\x2e\x6f\x72\x67"; // 11 nghttp2.org
$connection->write($headers);
// GOAWAY frame 0x07
$away = "\x00\x00\x00".
"\x07".
"\x00".
"\x00\x00\x00\x00".
"\x00\x00\x00\x01\x00\x00\x00\x00";
$connection->write($away);
}, function (Exception $e) {
echo 'Error: ' . $e->getMessage() . PHP_EOL;
});
Discussion