From 65be33a729d976045a608e23e7fe52996acff0fd Mon Sep 17 00:00:00 2001 From: tncrazvan Date: Fri, 8 Dec 2023 08:28:43 +0100 Subject: [PATCH] chore(docs): updating byte range requests docs --- docs/7.byte-range-requests.md | 118 ++++++---------------------------- 1 file changed, 20 insertions(+), 98 deletions(-) diff --git a/docs/7.byte-range-requests.md b/docs/7.byte-range-requests.md index 2820e578..5e2c62bb 100755 --- a/docs/7.byte-range-requests.md +++ b/docs/7.byte-range-requests.md @@ -18,130 +18,52 @@ Here's a simple example of how you would use the service: ```php use CatPaw\Web\Server; -use CatPaw\Web\Attributes\Header; -use CatPaw\Web\Attributes\Param; use CatPaw\Web\Services\ByteRangeService; use CatPaw\Web\Interfaces\ByteRangeWriterInterface; use Amp\Http\Response; -use function CatPaw\duplex; +use Amp\Http\Request; use Amp\Http\HttpStatus; use function Amp\File\getSize; -use Amp\File\File; -use function Amp\async; function main(){ $server = Server::create(); $server->router->get( path: "/{filename}", callback: function( - #[Param] string $filename, - #[Header("range")] false|array $range, - ByteRangeService $service, + string $filename, + Request $request, Response $response, - ){ - $service->response( - response: $response, - rangeQuery: $range[0]??"", - headers: [ - "Content-Type" => "text/html", - "Content-Length" => getSize($filename), - ], - interface: new class($filename) implements ByteRangeWriterInterface { - private File $file; - - public function __construct(private string $filename) { } - - public function start():void { - $this->file = openFile($this->filename, "r"); - } - - public function data(callable $emit, int $start, int $length):void { - $this->file->seek($start); - $data = $this->file->read($length); - $emit($data); - } - - public function end():void { - $this->file->close(); - } - } - ); - } - ); - $srver->start(); -} -``` - -Your endpoint will now serve bye range requests, but it will also throw an exception if the request is not a byte range -request or if the requested range is invalid.
-In those cases you can catch the exception and resume to a normal file buffering.
- -```php -use CatPaw\Web\Server; -use CatPaw\Web\Attributes\Header; -use CatPaw\Web\Attributes\Param; -use CatPaw\Web\Services\ByteRangeService; -use CatPaw\Web\Interfaces\ByteRangeWriterInterface; -use Amp\Http\Response; -use function CatPaw\duplex; -use Amp\Http\HttpStatus; -use function Amp\File\getSize; -use Amp\File\File; -use function Amp\async; - -function main(){ - $server = Server::create(); - $server->router->get( - path: "/{fileName}", - callback: function( - #[Param] string $fileName, - #[Header("range")] false|array $range, ByteRangeService $service, - Response $response, ){ try { - $service->response( - response: $response, - rangeQuery: $range[0]??"", - headers: [ - "Content-Type" => "text/html", - "Content-Length" => getSize($filename), - ], - interface: new class($filename) implements ByteRangeWriterInterface { - private File $file; - - public function __construct(private string $filename) { } - - public function start():void { - $this->file = openFile($this->filename, "r"); - } - - public function data(callable $emit, int $start, int $length):void { - $this->file->seek($start); - $data = $this->file->read($length); - $emit($data); - } - - public function end():void { - $this->file->close(); - } - } + $byteRangeResponse = $byteRange->file( + range: $request->getHeader("range") ?? '', + fileName: $fileName, ); + $response->setStatus($byteRangeResponse->getStatus()); + $response->setHeaders([ + ...(array)$byteRangeResponse->getHeaders(), + ...$attachmentHeaders, + ]); + $response->setBody($byteRangeResponse->getBody()); } catch(InvalidByteRangeQueryException) { + $fileSize = getSize($fileName); $response->setStatus(HttpStatus::OK); $response->setHeaders([ "Accept-Ranges" => "bytes", "Content-Type" => Mime::findContentType($fileName), "Content-Length" => $fileSize, - ...$extraHeaders, + ...$attachmentHeaders, ]); $response->setBody(openFile($fileName, 'r')); } - } + } ); - $server->start(); + $srver->start(); } ``` -Note that we're still letting the client know that we can serve byte range request by setting the `accpet-ranges: bytes` -header. +Your endpoint will now serve bye range requests. + +> [!Note] +> The `ByteRangeService::file` method throws a `InvalidByteRangeQueryException` exception whenever the given range query is not valid.