Skip to content

Commit

Permalink
feat: add new stream from
Browse files Browse the repository at this point in the history
  • Loading branch information
dewanakl committed Dec 26, 2023
1 parent 11aa0f8 commit 9dab4e2
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 29 deletions.
5 changes: 2 additions & 3 deletions src/Core/Facades/Web.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,12 @@ private function process(array $route): Respond|Stream
$attributeMiddleware = [];
if ($controller && $function) {
foreach ($this->app->getAttribute($controller, $function) as $value) {
$object = $this->app->make($value->getName());
$name = $value->getName();
$object = new $name();

if ($object instanceof MiddlewareInterface) {
$attributeMiddleware[] = $object;
}

$this->app->clean($value->getName());
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/Core/Http/Respond.php
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,7 @@ public function send(mixed $respond): void
$respond->push();
}

if ($respond instanceof Respond) {
if ($respond instanceof Respond && $respond->getContent()) {
fwrite($respond->getStream(), $respond->getContent(false));
}

Expand Down
122 changes: 98 additions & 24 deletions src/Core/Http/Stream.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@ public function __construct(Request $request, Respond $respond)
$this->respond = $respond;
}

/**
* Destroy object.
*
* @return void
*/
public function __destruct()
{
if (is_resource($this->file)) {
Expand All @@ -118,34 +123,21 @@ public function __destruct()
}

/**
* Init file.
* Init stream.
*
* @param bool $etag
* @return void
*/
private function init(bool $etag): void
private function init(): void
{
$hashFile = $etag ? @md5_file($this->path) : Hash::rand(10);
$type = $this->ftype($this->path);

if ($etag && $type != $this->ftype()) {
if (@trim($this->request->server->get('HTTP_IF_NONE_MATCH', '')) == $hashFile) {
$this->respond->setCode(304);
throw new StreamTerminate;
}

$this->respond->getHeader()->set('Etag', $hashFile);
}
$headers = $this->respond->getHeader()->all();
$this->respond->clean();
$this->respond->headers = new Header([...$headers, ...$this->respond->headers->all()]);

@set_time_limit(0);
@ignore_user_abort(true);

$this->file = @fopen($this->path, 'rb');
$this->name = @basename($this->path);
$this->boundary = $hashFile;
$this->size = @filesize($this->path);
$this->boundary = Hash::rand(10);
$this->download = false;
$this->type = $type;
}

/**
Expand All @@ -160,8 +152,8 @@ private function pushSingle(string $range): Closure

if ($start > 0 || $end < ($this->size - 1)) {
$this->respond->setCode(206);
$this->respond->getHeader()->set('Content-Length', strval($end - $start + 1));
$this->respond->getHeader()->set('Content-Range', sprintf('bytes %s-%s/%s', $start, $end, $this->size));
$this->respond->getHeader()->set('Content-Length', strval($end - $start + 1))
->set('Content-Range', sprintf('bytes %s-%s/%s', $start, $end, $this->size));

return function () use ($start, $end): void {
@fseek($this->file, $start);
Expand Down Expand Up @@ -363,6 +355,10 @@ private function ftype(string|null $typeFile = null): string
*/
public function process(): Stream
{
if (!is_resource($this->file)) {
return $this;
}

$this->stream = $this->respond->getStream();
$range = '';
$ranges = [];
Expand All @@ -378,7 +374,7 @@ public function process(): Stream
$this->respond->getHeader()
->set('Accept-Ranges', 'bytes')
->set('Content-Type', $this->type)
->set('Last-Modified', @gmdate(DateTimeInterface::RFC7231, @filemtime($this->path)))
->set('Last-Modified', @gmdate(DateTimeInterface::RFC7231, $this->path ? @filemtime($this->path) : null))
->set(
'Content-Disposition',
$this->type == $this->ftype()
Expand Down Expand Up @@ -409,6 +405,18 @@ public function push(): void
($this->callback)();
}

/**
* Callback for end of stream
*
* @param Closure $function
* @return Stream
*/
public function callback(Closure $function): Stream
{
$this->callback = $function;
return $this;
}

/**
* Download file.
*
Expand All @@ -435,9 +443,75 @@ public function send(string $filename): Stream
throw new NotFoundException;
}

$this->init();

$this->path = $filename;
$this->respond->clean();
$this->init(false);
$this->file = @fopen($this->path, 'rb');
$this->name = @basename($this->path);
$this->size = @filesize($this->path);
$this->type = $this->ftype($this->path);

return $this;
}

/**
* Add etag for stream response.
*
* @return Stream
*/
public function etag(): Stream
{
if ($this->path) {
$this->boundary = @md5_file($this->path);
}

if ($this->type == $this->ftype()) {
return $this;
}

if (@trim($this->request->server->get('HTTP_IF_NONE_MATCH', '')) == $this->boundary) {
$this->respond->setCode(304);
throw new StreamTerminate;
}

$this->respond->getHeader()->set('Etag', $this->boundary);
return $this;
}

/**
* Create new stream from string or resources
*
* @param mixed $content
* @param string $name
* @return Stream
*/
public function create(mixed $content, string $name): Stream
{
$this->init();
$this->name = @basename($name);
$this->type = $this->ftype($this->name);

if (is_resource($content)) {
$this->file = $content;
fseek($this->file, 0);
$contents = stream_get_contents($this->file);
fseek($this->file, 0);

$this->boundary = md5($contents);
$this->size = strlen($contents);

return $this;
}

$content = strval($content);

$this->file = fopen('php://memory', 'wb+');
fseek($this->file, 0);
fwrite($this->file, $content);
fseek($this->file, 0);

$this->boundary = md5($content);
$this->size = strlen($content);

return $this;
}
Expand Down
3 changes: 2 additions & 1 deletion src/Core/View/View.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Core\View;

use Core\View\Exception\CastToStringException;
use Error;
use ErrorException;
use LogicException;
use Stringable;
Expand Down Expand Up @@ -157,7 +158,7 @@ public function including(string $name): Render

return $template;
} catch (Throwable $th) {
if (!($th instanceof CastToStringException)) {
if (!($th instanceof ErrorException) && !($th instanceof Error) && !($th instanceof CastToStringException)) {
throw $th;
}

Expand Down

0 comments on commit 9dab4e2

Please sign in to comment.