/** * Get the message content as it becomes available. * * @see IncomingMessage::content() to get the content as a string. * * @see IncomingMessage::contentStream() to read the content from a stream. * * The returned promise is notified when content arrives. * @see https://github.com/reactphp/promise#extendedpromiseinterfaceprogress * * Cancelling the returned promise discards any remaining content. * * @return null [via promise] All content has been received. * @throws LogicException [via promise] The message content has already been consumed or discarded. */ public function contentUnbuffered() { if ($this->contentHandled) { return reject(new LogicException('The message content has already been consumed or discarded.')); } $this->contentHandled = true; if (0 === $this->headerFrame->contentLength) { return resolve(); } $deferred = new Deferred($this->cancelContentListener); $this->onBodyFrame = function ($exception, $frame, $final) use($deferred) { if ($exception) { $deferred->reject($exception); } else { $deferred->notify($frame->content); if ($final) { $deferred->resolve(); } } }; return $deferred->promise(); }