Question

A site I'm building serves a lot of images in a gallery. I want to utilize browser cache capabilities for these images. My backend is based on the principals of REST, and I'm using a controller method to serve images.

// check if the client validating cache and if it is current
$ifModified = Request::header('If-Modified-Since');
if (isset($ifModified) && (strtotime($ifModified) == filemtime($filePath . $fileName))) {
    // cache IS current, respond 304
    header('HTTP/1.0 304 Not Modified');
    exit();
} else {
    return new BinaryFileResponse(readfile($filePath . $fileName), 200,
        array(
            'Content-Type' => 'image/jpeg', // Guessing probably all jpegs.
            'Content-Transfer-Encoding' => 'binary',
            'Content-Disposition' => 'inline; filename="' . $fileName . '"',
            'Content-Length' => filesize($filePath . $fileName),
            'Expires' => date(DATE_RFC822, strtotime("+2 days")),
            'Last-Modified' => date(DATE_RFC822, \Illuminate\Support\Facades\File::lastModified($filePath . $fileName)),
            'Cache-Control' => 'public, max-age=10800, pre-check=10800',
            'Pragma' => 'public',
        ), true, 'inline');
}

When running this through my localhost, the response headers are:

HTTP/1.1 200 OK
Date: Mon, 05 May 2014 18:12:56 GMT
Server: Apache/2.4.4 (Win64) PHP/5.4.12
X-Powered-By: PHP/5.4.12
Content-Transfer-Encoding: binary
Content-Disposition: inline; filename="2930..jpg"
Content-Length: 17080
Expires: Wed, 07 May 14 18:12:57 +0000
Cache-Control: max-age=10800, pre-check=10800, public
Last-Modified: Mon, 05 May 14 11:43:08 +0000
Pragma: public
X-Frame-Options: SAMEORIGIN
X-UA-Compatible: IE=edge,chrome=1
Keep-Alive: timeout=5, max=97
Connection: Keep-Alive
Content-Type: image/jpeg

When running the site through my hosting provider, the response headers are:

HTTP/1.1 200 OK
Date: Mon, 05 May 2014 18:29:24 GMT
Server: Apache/2.2.27 (Unix) mod_ssl/2.2.27 OpenSSL/1.0.1e-fips mod_bwlimited/1.4
X-Powered-By: PHP/5.4.27
Cache-Control: max-age=0
Expires: Mon, 05 May 2014 18:29:24 GMT
X-UA-Compatible: IE=edge,chrome=1
Keep-Alive: timeout=5, max=96
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html; charset=utf-8

I'm using a .htaccess file wihch is identical on both localhost and my hosting provider. Besides the differences in Apache and PHP versions, I'm guessing that this might be a server configuration issue. What do I look for in order to find out why the backend running on the host is not transmitting the correct headers to the client?

Was it helpful?

Solution 2

My bad. I'm such a smurf!

This code works:

// check if the client validating cache and if it is current
$ifModified = Request::header('If-Modified-Since');
if (isset($ifModified) && (strtotime($ifModified) == filemtime($filePath . $fileName))) {
    // cache IS current, respond 304
    header('HTTP/1.0 304 Not Modified');
    exit();
} else {
    return new BinaryFileResponse($filePath . $fileName, 200,
        array(
            'Content-Type' => 'image/jpeg', // Guessing probably all jpegs.
            'Content-Transfer-Encoding' => 'binary',
            'Content-Disposition' => 'inline; filename="' . $fileName . '"',
            'Content-Length' => filesize($filePath . $fileName),
            'Expires' => date(DATE_RFC822, strtotime("+2 days")),
            'Last-Modified' => date(DATE_RFC822, \Illuminate\Support\Facades\File::lastModified($filePath . $fileName)),
            'Cache-Control' => 'public, max-age=10800, pre-check=10800',
            'Pragma' => 'public',
        ), true, 'inline');
}

Since I'm returning a Binary File Response, I of course should not read the file before handing it over. The response constructor expects a file name, not the data. Anyway, this uncovered that there were never any problems with the response headers at all.

The response failed and I got the headers accordingly. But since I read in the data from the image file, the data went along as the body of the request anyway. Which was the reason I did not catch the error.

OTHER TIPS

Take a look at this question: Cannot set Cache-Control in Laravel 4

They suggest using BinaryFileResponse as you are, but they're using the actual methods of that class to set the various settings. Perhaps it's an issue with parsing the values you're passing.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top