public function writer(InternalRequest $ireq) : \Generator
{
$client = $ireq->client;
$id = $ireq->streamId;
$headers = yield;
unset($headers[":reason"], $headers["connection"]);
// obsolete in HTTP/2.0
$headers = HPack::encode($headers);
// @TODO decide whether to use max-frame size
if (\strlen($headers) > 16384) {
$split = str_split($headers, 16384);
$headers = array_shift($split);
$this->writeFrame($client, $headers, self::HEADERS, self::NOFLAG, $id);
$headers = array_pop($split);
foreach ($split as $msgPart) {
$this->writeFrame($client, $msgPart, self::CONTINUATION, self::NOFLAG, $id);
}
$this->writeFrame($client, $headers, self::CONTINUATION, self::END_HEADERS, $id);
} else {
$this->writeFrame($client, $headers, self::HEADERS, self::END_HEADERS, $id);
}
$msgs = "";
while (($msgPart = yield) !== null) {
$msgs .= $msgPart;
if ($msgPart === false || \strlen($msgs) > $client->options->outputBufferSize) {
$this->writeData($client, $msgs, $id, false);
$msgs = "";
}
if ($client->isDead) {
if (!$client->bufferPromisor) {
$client->bufferPromisor = new Deferred();
$client->bufferPromisor->fail(new ClientException());
}
while (true) {
yield;
}
}
}
$this->writeData($client, $msgs, $id, true);
if ($client->isDead && !$client->bufferPromisor) {
$client->bufferPromisor = new Failure(new ClientException());
}
if ($client->bufferPromisor) {
$keepAlives =& $client->remainingKeepAlives;
// avoid cyclic reference
$client->bufferPromisor->when(static function () use(&$keepAlives) {
$keepAlives++;
});
} else {
$client->remainingKeepAlives++;
}
}