Skip to content

Commit

Permalink
gui/proxy: Prevent browser caching on all requests (#2091)
Browse files Browse the repository at this point in the history
When the client encounters a network issue on Windows or macOS, it
sometimes "caches" this response and will return it to every subsequent
request.

We make the assumption that this "cache" is handled by Chromium and as
such can be disabled by adding the `Cache-Control: no-cache` header to
all responses.
Since we don't want the remote Cozy to do this (and thus disable
useful caches for all clients) we define an Electron response hook to
add it on the client side.

We've seen improvements during a test phase but don't have any hard
evidence that this really solves the issue.
  • Loading branch information
taratatach authored May 11, 2021
1 parent 2115474 commit bb5cd92
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 2 deletions.
11 changes: 11 additions & 0 deletions gui/js/proxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,17 @@ const setup = async (
callback(-3) // use chrome validation
})

// It's unclear if this actually works or not especially since we can't
// control that the Cache-Control header is really set.
// See https://github.com/electron/electron/issues/27895.
syncSession.webRequest.onHeadersReceived(
({ statusLine, responseHeaders }, callback) => {
responseHeaders['Cache-Control'] = ['no-store']
statusLine += ' NO CACHE'
callback({ responseHeaders, statusLine })
}
)

app.on(
'select-client-certificate',
(event, webContents, url, list, callback) => {
Expand Down
17 changes: 16 additions & 1 deletion test/unit/gui/proxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,26 @@ describe('gui/js/proxy', function() {

describe('fetch()', () => {
describe('HTTP', () => {
beforeEach(() => global.fetch(httpUrl()))
let response
beforeEach(async () => {
response = await global.fetch(httpUrl())
})

it('sets User-Agent', async () => {
should(received.headers['user-agent']).equal(userAgent)
})

// FIXME: Returned response headers only contain the raw headers which
// are not modified by calls to onHeadersReceived.
// See https://github.com/electron/electron/issues/27895
//
// This means we can't see if the Cache-Control header is actually
// set.
// But it should still be interpreted by Chromium.
it.skip('sets reponse Cache-Control header to no-store', async () => {
// Prevent Chromium from caching requests to avoid net error loops
should(response.headers['Cache-Control']).equal('no-store')
})
})

// TODO: fetch + self-signed pfx
Expand Down
4 changes: 3 additions & 1 deletion test/unit/remote/cozy.js
Original file line number Diff line number Diff line change
Expand Up @@ -606,7 +606,9 @@ describe('RemoteCozy', function() {

const stubWarningsResponse = (status /*: number */, data) => {
cozyStackDouble.stub((req, res) => {
if (req.url === '/status/') res.end('{}')
// A strict equality check would prevent us from adding query-string
// parameters to the request.
if (req.url.includes('/status/')) res.end('{}')
else {
res.writeHead(status)
res.end(JSON.stringify(data))
Expand Down

0 comments on commit bb5cd92

Please sign in to comment.