📖
【PHP】HTTP/2 の Settings フレームペイロードの生成
Settings フレームのペイロードは2バイトの識別子と4バイトの値で構成される。識別子として次のものが定義される。
- SETTINGS_HEADER_TABLE_SIZE (0x01)
- SETTINGS_ENABLE_PUSH (0x02)
- SETTINGS_MAX_CONCURRENT_STREAMS (0x03)
- SETTINGS_INITIAL_WINDOW_SIZE (0x04)
- SETTINGS_MAX_FRAME_SIZE (0x05)
- SETTINGS_MAX_HEADER_LIST_SIZE (0x06)
6つの識別子をすべて使うならペイロードのサイズは36バイト(6 * 6)となる。次のテストコードのデータは SETTINGS_ENABLE_PUSH (0x02)
をオフにする、SETTINGS_MAX_CONCURRENT_STREAMS (0x03)
の値を 100 (0x64)
にするというものである。
<?php
// https://gist.github.com/masakielastic/8e93e3ad771be0cef0081f23bd9b35a2
require 'h2utils.php';
$options = [
[0x2, 0x0],
[0x3, 0x64]
];
$settings = [
"length" => "\x00\x00\x0C",
"type" => "\x04",
"flag" => "\x00",
"streamId" => "\x00\x00\x00\x00",
"payload" => "\x00\x02"."\x00\x00\x00\x00".
"\x00\x03"."\x00\x00\x00\x64"
];
var_dump(
$settings['payload'] === createSettingsFramePayload($options),
$options === settingsFramePayloadToArray($settings['payload']),
implode($settings) === createSettingsFrame($options)
);
function createSettingsFrame(array $options = [], int $flag = 0x0): string
{
$payload = createSettingsFramePayload($options);
$length = strlen($payload);
return createFrameHeader($length, 0x4, $flag, 0x0).$payload;
}
function createSettingsFramePayload(array $options): string
{
$ret = '';
foreach ($options as $values) {
$ret .= int16ToBin($values[0]).int32ToBin($values[1]);
}
return $ret;
}
function settingsFramePayloadToArray(string $bytes): array
{
$size = strlen($bytes);
$pos = 0;
$ret = [];
while ($pos < $size) {
$ret[] = [
binToInt16(substr($bytes, $pos, 2)),
binToInt32(substr($bytes, $pos + 2, 4))
];
$pos += 6;
}
return $ret;
}
Discussion