Search code examples
phpgoogle-chromespdyslim-3psr-7

Image only loading some of the time when streamed(?) to client


I've been writing a web app for some time now, and I've been running into some issues with serving images.

My code pulls file data from the server, using file_get_contents, and uses Slim's Request object's write method to output the contents of the file, setting the headers as it goes. For most files, this works, however larger images often only show a gray outline of the image dimensions (tested in mobile and desktop Chrome). Requests error out with ERR_SPDY_PROTOCOL_ERROR, which led me to believe it was an HTTP 2 issue (the server I test on listens for HTTP 2 connections, set with the listen [port] http2 directive in its nginx config), however I attempted to downgrade the HTTP version used in the response with PSR-7's RequestInterface's withProtocolVersion method and nothing changed.

I know using file_get_contents then outputting said contents is a very roundabout way to do things, but it's the only way I know to allow users of this app to arbitrarily set the location of uploaded files.

This is the most relevant part of my code, where $filepath is the path to the file the user requested. This code works as expected for all files except for large images.

return $response->withHeader('Content-Type', mime_content_type($filepath))->write(file_get_contents($filepath));

Solution

  • I solved this using Guzzle's LazyOpenStream class. Seems to work flawless now!

    Edit: So, while this didn't initially appear to work, it turns out some file permissions were screwed up on nginx's end since I changed the user---nginx no longer owned its FastCGI cache directory. That's fortunately been fixed now, and everything seems to work.
    Protip if you're in my situation: Read The Frackin' Logs!