rstacruz / sinatra-assetpack

Package your assets transparently in Sinatra.
http://ricostacruz.com/sinatra-assetpack/
MIT License
542 stars 97 forks source link

Browser does not cache dynamic assets served with Assetpack. No `Last-Modified` header? #111

Closed lolmaus closed 11 years ago

lolmaus commented 11 years ago

Hi!

I'm trying to make use of Assetpack in its very basic form.

My problem is that my browser (Firefox) redownloads dynamic assets every time, while Assetpack documentation claims that they should be cached.

By "dynamic assets" i mean compiled SASS and minified JS.

Static assets are cached properly.

I've carefully examined headers of server replies for dynamic and static assets and i noticed a difference: for static assets, Sinatra sends the Last-Modified header, and in the subsequent request the browser sends the If-Modified-Since header. But with dynamic assts, Sinatra does not send the Last-Modified header, and therefore browser does not ask for If-Modified-Since.

Here's my app code.

Please help me resolve this.

j15e commented 11 years ago

Thanks for reporting, will look into this. Are you running in production env?

j15e commented 11 years ago

Works for me both in dev & production

Request URL:http://localhost:9292/js/app.eda5890b3fc45b14b5e473069efad031.js
Request Method:GET
Status Code:200 OK

HTTP/1.1 200 OK
Content-Type: application/javascript;charset=utf-8
Last-Modified: Sat, 20 Apr 2013 19:48:39 GMT
X-Content-Type-Options: nosniff
Server: WEBrick/1.3.1 (Ruby/1.9.3/2013-05-15)
Date: Mon, 10 Jun 2013 04:09:43 GMT
Content-Length: 93185
Connection: Keep-Alive

then

Request URL:http://localhost:9292/js/app.eda5890b3fc45b14b5e473069efad031.js
Request Method:GET
Status Code:304 Not Modified

HTTP/1.1 304 Not Modified
X-Content-Type-Options: nosniff
Server: WEBrick/1.3.1 (Ruby/1.9.3/2013-05-15)
Date: Mon, 10 Jun 2013 04:10:35 GMT
Connection: close

Could you provide more details about your setup?

Are you serving pre-compiled assets? If so, your web server must ensure those headers are sent, it's not going thought sinatra if they are compiled in public/.

Also, what version of sinatra & sinatra-assetpack?

lolmaus commented 11 years ago

Hey @j15e, thank you for a detailed reply!

I've shared a link to my crapplication above. Could you please try running it and see whether my issue takes place for you? You could also look into my code, it's very small (the application is pure JS except for one POST request parsed by Sinatra).

Version numbers are also in the repo. I believe they are latest stables.

j15e commented 11 years ago

Works for me, must be something with your browser, have you disabled caching in the Chrome console? :

➜  sassbin git:(39c0963) ✗ rackup
>> Thin web server (v1.5.1 codename Straight Razor)
>> Maximum connections set to 1024
>> Listening on 0.0.0.0:9292, CTRL+C to stop
127.0.0.1 - - [10/Jun/2013 10:42:58] "GET / HTTP/1.1" 200 7313 0.4201
127.0.0.1 - - [10/Jun/2013 10:42:58] "GET /css/jquery-ui-1.10.3.custom.min.13b81cdc74b202604968a2e4e6328910.css HTTP/1.1" 200 16781 0.0105
127.0.0.1 - - [10/Jun/2013 10:43:00] "GET /css/style.072c252b130ad7ddc7dd5ea7bbc4637e.css HTTP/1.1" 200 7158 2.0698
127.0.0.1 - - [10/Jun/2013 10:43:00] "GET /js/app/common/abortRequests.1f30c6e9bbed972b6a831c0f4112ece7.js HTTP/1.1" 200 - 0.0069
127.0.0.1 - - [10/Jun/2013 10:43:00] "GET /js/app/common/activate.13e15205b09fca728aaccf6a88bb99c7.js HTTP/1.1" 200 - 0.0033
127.0.0.1 - - [10/Jun/2013 10:43:00] "GET /js/app/common/percentage.3d0593f57abe691337a6f9e7a88bee32.js HTTP/1.1" 200 - 0.0017
127.0.0.1 - - [10/Jun/2013 10:43:00] "GET /js/app/compilation/compileHtml.625b452b2b9f62cd894f4008466e258a.js HTTP/1.1" 200 - 0.0019
127.0.0.1 - - [10/Jun/2013 10:43:01] "GET /js/app/compilation/compileSass.af38ecb4cf82c3264f92aae0a3cb4d38.js HTTP/1.1" 200 - 0.1192
127.0.0.1 - - [10/Jun/2013 10:43:01] "GET /js/app/editors/editorWrapToggle.928a9437885e7332bb930a371471a90d.js HTTP/1.1" 200 - 0.0051
127.0.0.1 - - [10/Jun/2013 10:43:01] "GET /js/app/compilation/compileSassWithDelay.bfb3f27880684fc4f2c4e6bd00fcb512.js HTTP/1.1" 200 - 0.1722
127.0.0.1 - - [10/Jun/2013 10:43:01] "GET /js/app/config/configLoad.83a4f79a784d5564756adc68f3e58aa6.js HTTP/1.1" 200 - 0.0251
127.0.0.1 - - [10/Jun/2013 10:43:01] "GET /js/app/config/configSave.1e2c6ff9ec22e7ad8763618d369ecce1.js HTTP/1.1" 200 - 0.0302
127.0.0.1 - - [10/Jun/2013 10:43:01] "GET /js/app/editors/loadEditors.20b3efa26b77c4bf27c2cc31329e333f.js HTTP/1.1" 200 - 0.0022
127.0.0.1 - - [10/Jun/2013 10:43:01] "GET /js/app/editors/resizeEditor.ab4be651de0977c4947f854635bd788d.js HTTP/1.1" 200 - 0.0026
127.0.0.1 - - [10/Jun/2013 10:43:01] "GET /js/app/gists/loadCurrentGist.554f680c5ec21415d5d2dcc0a35bd666.js HTTP/1.1" 200 - 0.0572
127.0.0.1 - - [10/Jun/2013 10:43:01] "GET /js/app/gists/loadGist.9457355697fd2c34fc5981b2d00e0b80.js HTTP/1.1" 200 - 0.0091
127.0.0.1 - - [10/Jun/2013 10:43:01] "GET /js/app/gists/newGist.bef0f58d4a3f4e6356b1a6b613ef7474.js HTTP/1.1" 200 - 0.0021
127.0.0.1 - - [10/Jun/2013 10:43:01] "GET /js/app/gists/promptGist.406a84d9502e449bf78f856a759e3177.js HTTP/1.1" 200 - 0.0021
127.0.0.1 - - [10/Jun/2013 10:43:01] "GET /js/app/gists/saveGist.e233787a4388f817b5307db2573b9c75.js HTTP/1.1" 200 - 0.0021
127.0.0.1 - - [10/Jun/2013 10:43:01] "GET /js/app/panes/applyResizableToPanes.f0eae96e909883e8f259062188f65035.js HTTP/1.1" 200 - 0.0149
127.0.0.1 - - [10/Jun/2013 10:43:01] "GET /js/app/panes/equalize.927a41330e65c3a617aa96868f36cef5.js HTTP/1.1" 200 - 0.0021
127.0.0.1 - - [10/Jun/2013 10:43:01] "GET /js/app/panes/resetPanes.34f17a402815ed9507a384161f5d371f.js HTTP/1.1" 200 - 0.0072
127.0.0.1 - - [10/Jun/2013 10:43:01] "GET /js/app/panes/togglePane.e9aa09507266f77da2c2876e2c5c0dd1.js HTTP/1.1" 200 - 0.0025
127.0.0.1 - - [10/Jun/2013 10:43:01] "GET /js/app/status/appStatus.001ed80feea8253858483c814fb11927.js HTTP/1.1" 200 - 0.0543
127.0.0.1 - - [10/Jun/2013 10:43:01] "GET /js/app/status/statusBar.16a4fc1accee3b1041a5fd6494840cd8.js HTTP/1.1" 200 - 0.0205
127.0.0.1 - - [10/Jun/2013 10:43:01] "GET /js/app/editors.4bfcbb8c5c8f27f602fbaa54379f41bb.js HTTP/1.1" 200 - 0.0019
127.0.0.1 - - [10/Jun/2013 10:43:01] "GET /js/app/gists.ba54948d2f66b0f461a42521ccbc1731.js HTTP/1.1" 200 - 0.0022
127.0.0.1 - - [10/Jun/2013 10:43:01] "GET /js/app/panes.6f5e2006c42c06a5cb30046fe68af53c.js HTTP/1.1" 200 - 0.0218
127.0.0.1 - - [10/Jun/2013 10:43:01] "GET /js/app/status.64a734c1b9744f7000a3c62db267dac9.js HTTP/1.1" 200 - 0.0030
127.0.0.1 - - [10/Jun/2013 10:43:01] "GET /images/waiting.png HTTP/1.1" 200 - 0.0050
127.0.0.1 - - [10/Jun/2013 10:43:01] "GET /images/awesome.png HTTP/1.1" 200 - 0.0074
127.0.0.1 - - [10/Jun/2013 10:43:01] "GET /images/draggable.png HTTP/1.1" 200 - 0.0027
127.0.0.1 - - [10/Jun/2013 10:43:03] "GET /js/vendor-static/ace/worker-css.js HTTP/1.1" 200 - 0.0111
127.0.0.1 - - [10/Jun/2013 10:43:03] "GET /favicon.ico HTTP/1.1" 404 480 0.0037
127.0.0.1 - - [10/Jun/2013 10:43:12] "GET / HTTP/1.1" 200 7313 0.1212
127.0.0.1 - - [10/Jun/2013 10:43:12] "GET /js/app/common/abortRequests.1f30c6e9bbed972b6a831c0f4112ece7.js HTTP/1.1" 304 - 0.0025
127.0.0.1 - - [10/Jun/2013 10:43:12] "GET /js/app/common/activate.13e15205b09fca728aaccf6a88bb99c7.js HTTP/1.1" 304 - 0.0020
127.0.0.1 - - [10/Jun/2013 10:43:12] "GET /js/app/common/percentage.3d0593f57abe691337a6f9e7a88bee32.js HTTP/1.1" 304 - 0.0036
127.0.0.1 - - [10/Jun/2013 10:43:12] "GET /js/app/compilation/compileHtml.625b452b2b9f62cd894f4008466e258a.js HTTP/1.1" 304 - 0.0014
127.0.0.1 - - [10/Jun/2013 10:43:12] "GET /js/app/compilation/compileSass.af38ecb4cf82c3264f92aae0a3cb4d38.js HTTP/1.1" 304 - 0.0018
127.0.0.1 - - [10/Jun/2013 10:43:12] "GET /js/app/compilation/compileSassWithDelay.bfb3f27880684fc4f2c4e6bd00fcb512.js HTTP/1.1" 304 - 0.0029
127.0.0.1 - - [10/Jun/2013 10:43:12] "GET /js/app/config/configLoad.83a4f79a784d5564756adc68f3e58aa6.js HTTP/1.1" 304 - 0.0063
127.0.0.1 - - [10/Jun/2013 10:43:12] "GET /js/app/config/configSave.1e2c6ff9ec22e7ad8763618d369ecce1.js HTTP/1.1" 304 - 0.0045
127.0.0.1 - - [10/Jun/2013 10:43:12] "GET /js/app/editors/editorWrapToggle.928a9437885e7332bb930a371471a90d.js HTTP/1.1" 304 - 0.0226
127.0.0.1 - - [10/Jun/2013 10:43:12] "GET /js/app/editors/loadEditors.20b3efa26b77c4bf27c2cc31329e333f.js HTTP/1.1" 304 - 0.0188
127.0.0.1 - - [10/Jun/2013 10:43:12] "GET /js/app/editors/resizeEditor.ab4be651de0977c4947f854635bd788d.js HTTP/1.1" 304 - 0.0017
127.0.0.1 - - [10/Jun/2013 10:43:12] "GET /js/app/gists/loadCurrentGist.554f680c5ec21415d5d2dcc0a35bd666.js HTTP/1.1" 304 - 0.0021
127.0.0.1 - - [10/Jun/2013 10:43:12] "GET /js/app/gists/loadGist.9457355697fd2c34fc5981b2d00e0b80.js HTTP/1.1" 304 - 0.0017
127.0.0.1 - - [10/Jun/2013 10:43:13] "GET /js/app/gists/newGist.bef0f58d4a3f4e6356b1a6b613ef7474.js HTTP/1.1" 304 - 0.0076
127.0.0.1 - - [10/Jun/2013 10:43:13] "GET /js/app/gists/promptGist.406a84d9502e449bf78f856a759e3177.js HTTP/1.1" 304 - 0.0264
127.0.0.1 - - [10/Jun/2013 10:43:13] "GET /js/app/gists/saveGist.e233787a4388f817b5307db2573b9c75.js HTTP/1.1" 304 - 0.0017
127.0.0.1 - - [10/Jun/2013 10:43:13] "GET /js/app/panes/applyResizableToPanes.f0eae96e909883e8f259062188f65035.js HTTP/1.1" 304 - 0.0024
127.0.0.1 - - [10/Jun/2013 10:43:13] "GET /js/app/panes/equalize.927a41330e65c3a617aa96868f36cef5.js HTTP/1.1" 304 - 0.0015
127.0.0.1 - - [10/Jun/2013 10:43:13] "GET /js/app/panes/resetPanes.34f17a402815ed9507a384161f5d371f.js HTTP/1.1" 304 - 0.0020
127.0.0.1 - - [10/Jun/2013 10:43:13] "GET /js/app/panes/togglePane.e9aa09507266f77da2c2876e2c5c0dd1.js HTTP/1.1" 304 - 0.0056
127.0.0.1 - - [10/Jun/2013 10:43:13] "GET /js/app/status/appStatus.001ed80feea8253858483c814fb11927.js HTTP/1.1" 304 - 0.0019
127.0.0.1 - - [10/Jun/2013 10:43:13] "GET /js/app/status/statusBar.16a4fc1accee3b1041a5fd6494840cd8.js HTTP/1.1" 304 - 0.0019
127.0.0.1 - - [10/Jun/2013 10:43:13] "GET /js/app/editors.4bfcbb8c5c8f27f602fbaa54379f41bb.js HTTP/1.1" 304 - 0.0037
127.0.0.1 - - [10/Jun/2013 10:43:13] "GET /js/app/gists.ba54948d2f66b0f461a42521ccbc1731.js HTTP/1.1" 304 - 0.0016
127.0.0.1 - - [10/Jun/2013 10:43:13] "GET /js/app/panes.6f5e2006c42c06a5cb30046fe68af53c.js HTTP/1.1" 304 - 0.0017
127.0.0.1 - - [10/Jun/2013 10:43:13] "GET /js/app/status.64a734c1b9744f7000a3c62db267dac9.js HTTP/1.1" 304 - 0.0019
127.0.0.1 - - [10/Jun/2013 10:43:13] "GET /images/waiting.png HTTP/1.1" 304 - 0.0018
127.0.0.1 - - [10/Jun/2013 10:43:13] "GET /images/awesome.png HTTP/1.1" 304 - 0.0047
127.0.0.1 - - [10/Jun/2013 10:43:14] "GET /images/draggable.png HTTP/1.1" 304 - 0.0020
127.0.0.1 - - [10/Jun/2013 10:43:16] "GET /js/vendor-static/ace/worker-css.js HTTP/1.1" 304 - 0.0017
127.0.0.1 - - [10/Jun/2013 10:43:16] "GET /favicon.ico HTTP/1.1" 404 480 0.0043
lolmaus commented 11 years ago

In development mode the log looks the same for me. JS files are not minified and served separately with proper caching. The only difference is that CSS is redownloaded every time but i believe it's due to cache_dynamic_assets not enabled (and the styles are originally in SASS).

The issue persists for me in production. Here's how the log looks for me (both in Firefox and Chrome): http://d.pr/i/bswN+ I provide the client-side log because server console won't show the log in production mode for some reason.

The files served by rawgithub.com are redownloaded due to a known bug in rawgithub.com. But i don't understand why those local files with cache-busting prefixes are redownloaded every time (the prefixes don't change).

Can you please try to open my production server: http://sassbin.com and see whether it is the same for you?

j15e commented 11 years ago

Man, this one was a real Sherlock Holmes mystery! Haven't found the very exact cause even using a debugger & diving into gems code, I abandon on the real source, but found two fixes :

1 - remove sinatra-support which is way deprecated & seems to conflict with sinatra-assetpack on dealing with last-modified

2 - update to sinatra-assetpack master which now has an improvement fixing this as a side effect : Sending a Time object as expected by sinatra helper last_modified seems to also fix your specific issue, but man I got no clue why.

j15e commented 11 years ago

Just released 0.2.5

lolmaus commented 11 years ago

Yay, updated Sinatra-Assetpack, and now it works!