/**
  * 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();
 }