diff --git a/src/main/php/web/Response.class.php b/src/main/php/web/Response.class.php index d23776d9..a369eeab 100755 --- a/src/main/php/web/Response.class.php +++ b/src/main/php/web/Response.class.php @@ -1,6 +1,8 @@ transmit(...)` instead! * @param io.streams.InputStream $in * @param string $mediaType * @param int $size If omitted, uses chunked transfer encoding @@ -188,11 +191,43 @@ public function transfer($in, $mediaType= 'application/octet-stream', $size= nul } } + /** + * Transmits a given source to the output asynchronously. + * + * @param io.Channel|io.streams.InputStream $source + * @param string $mediaType + * @param int $size If omitted, uses chunked transfer encoding + * @return iterable + * @throws lang.IllegalArgumentException + */ + public function transmit($source, $mediaType= 'application/octet-stream', $size= null) { + if ($source instanceof InputStream) { + $in= $source; + } else if ($source instanceof Channel) { + $in= $source->in(); + } else { + throw new IllegalArgumentException('Expected either a channel or an input stream, have '.typeof($source)); + } + + $this->headers['Content-Type']= [$mediaType]; + $out= $this->stream($size); + try { + while ($in->available()) { + $out->write($in->read()); + yield; + } + } finally { + $out->close(); + $in->close(); + } + } + /** * Sends some content * * @param string $content * @param string $mediaType + * @return void */ public function send($content, $mediaType= 'text/html') { $this->headers['Content-Type']= [$mediaType]; diff --git a/src/test/php/web/unittest/ResponseTest.class.php b/src/test/php/web/unittest/ResponseTest.class.php index a78baf4f..7ffae488 100755 --- a/src/test/php/web/unittest/ResponseTest.class.php +++ b/src/test/php/web/unittest/ResponseTest.class.php @@ -1,12 +1,14 @@ transmit(new MemoryInputStream('