Header parsing improvements

* Made headers public readonly in HeadersFrame
* Fetching headers by value implemented
* Initial tests for HeaderBag
This commit is contained in:
Chris 2024-07-25 14:41:21 +02:00
parent 5c2279a544
commit d41cfb1be2
3 changed files with 69 additions and 1 deletions

View File

@ -2,7 +2,26 @@
namespace NoccyLabs\React\Http2\Frame; namespace NoccyLabs\React\Http2\Frame;
use NoccyLabs\React\Http2\Header\HeaderBag;
use NoccyLabs\React\Http2\Header\HeaderPacker;
class HeadersFrame extends Frame class HeadersFrame extends Frame
{ {
static ?HeaderPacker $headerPacker = null;
public readonly HeaderBag $headers;
public function fromBinary(string $binary): void
{
if (!self::$headerPacker)
self::$headerPacker = new HeaderPacker();
$this->headers = self::$headerPacker->unpackHeaders($binary);
}
public function toBinary(): string
{
return self::$headerPacker->packHeaders($this->headers);
}
} }

View File

@ -25,7 +25,23 @@ class HeaderBag implements IteratorAggregate
public function append(string $name, string $value) public function append(string $name, string $value)
{ {
$this->headers[] = [ $name, $value ]; $this->headers[] = [$name, $value ];
}
public function getAllHeaders(): array
{
return $this->headers;
}
public function getHeaders(string $name): ?array
{
return array_map(fn($v) => $v[1], array_filter($this->headers, fn($v) => $v[0] == $name));
}
public function getHeaderLine(string $name): ?string
{
$headers = $this->getHeaders($name);
return array_shift($headers);
} }
public function getIterator(): Traversable public function getIterator(): Traversable

View File

@ -0,0 +1,33 @@
<?php
namespace NoccyLabs\React\Http2\Header;
use PHPUnit\Framework\Attributes\CoversClass;
#[CoversClass(HeaderBag::class)]
#[CoversClass(HeaderPacker::class)]
class HeaderBagTest extends \PHPUnit\Framework\TestCase
{
public function testHeadersInExamplesFromRfc7541()
{
$packer = new HeaderPacker();
$in = "\x82\x86\x84\x41\x8c\xf1\xe3\xc2\xe5\xf2\x3a\x6b\xa0\xab\x90\xf4\xff";
$expect = new HeaderBag([
':method' => 'GET',
':scheme' => 'http',
':path' => '/',
':authority' => 'www.example.com'
]);
$out = $packer->unpackHeaders($in);
$this->assertEquals('GET', $out->getHeaderLine(':method'));
$this->assertEquals('http', $out->getHeaderLine(':scheme'));
$this->assertEquals('/', $out->getHeaderLine(':path'));
$this->assertEquals('www.example.com', $out->getHeaderLine(':authority'));
}
}