Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE] Send files directly with Swoole Response. #6

Merged
merged 2 commits into from
Feb 19, 2022

Conversation

hbsolutions-ru
Copy link
Contributor

Send files directly with Swoole Response.

Copy link
Owner

@imefisto imefisto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi !

Please, could you provide examples of how are you using this feature?

Thank you!

@hbsolutions-ru
Copy link
Contributor Author

I'm using this Swoole's feature to send quite large files directly with Swoole server and avoid in-memory copying. This trick allowed me to return files faster.

My example:

    public function get(Response $response, array $data): Response
    {
        $this->validate($data);

        $media = $this->getMedia(intval($data['mediaId']));

        return $response
            ->withHeader('Content-Type', $media->mediaType)
            ->withHeader('Content-Transfer-Encoding', 'binary')
            ->withHeader('Expires', date(DateTimeFormat::HTTP, time() + self::HEADER_CACHE_TIME))
            ->withHeader('Cache-Control', 'max-age=' . self::HEADER_CACHE_TIME)
            ->withBody(
                (new StreamFactory())->createStreamFromFile($media->originPath, 'rb')
            );
    }

@imefisto
Copy link
Owner

Thank you for the example!

I'm not able to get STDIO/coroutine and plainfile/coroutine for stream_type and wrapper_type respectively. I'm using the Nyholm's PsrFactory to create the streams. When I print the stream's metadata I'm getting something like this:

Array
(
    [timed_out] => 
    [blocked] => 1
    [eof] => 
    [wrapper_type] => plainfile
    [stream_type] => STDIO
    [mode] => r
    [unread_bytes] => 0
    [seekable] => 1
    [uri] => /some/path/test.png
)

Which factory are you using to execute the createStreamFromFile function? I'm asking this because I would like to know if the trick you're proposing can be used with different PSR factories.

Thanks again!

@hbsolutions-ru
Copy link
Contributor Author

It is a good point. Thank you!

I'm using Slim's Factory and my whole example is here.
I tried it with Nyholm\Psr7\Factory\Psr17Factory but have the same behavior:

array(9) {
  ["timed_out"]=>
  bool(false)
  ["blocked"]=>
  bool(true)
  ["eof"]=>
  bool(false)
  ["wrapper_type"]=>
  string(19) "plainfile/coroutine"
  ["stream_type"]=>
  string(15) "STDIO/coroutine"
  ["mode"]=>
  string(2) "rb"
  ["unread_bytes"]=>
  int(0)
  ["seekable"]=>
  bool(true)
  ["uri"]=>
  string(25) "/var/www/static/image.jpg"
}

Finally I found the root cause... Coroutines were enabled in my code: Swoole\Runtime::enableCoroutine(true, SWOOLE_HOOK_ALL);
When I switched them off (Swoole\Runtime::enableCoroutine(false)) than I get the similar result like you.

Anyway I will improve my code to handle both cases. When done I will update the pull request.

@imefisto
Copy link
Owner

Nice catch! Now I'm able to get the "/coroutine" too.

Thank you!

@hbsolutions-ru
Copy link
Contributor Author

@imefisto I've committed the fix to handle both cases.

@imefisto
Copy link
Owner

I'm merging now, then I'll add a test case for the feature.

Thank you very much!

@imefisto imefisto merged commit 7f8a9e4 into imefisto:master Feb 19, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants