Fix flash errors in performance bar for cached responses

When a request contains an ETag value in its If-None-Match header, the backend
may send a request ID (from Rack) that does not correspond to a value in Peek's
Redis cache (because we aborted the Rails processing in our ETag middleware).

Because a cached response (304) has to replace the headers with those from the
previous 200 - https://tools.ietf.org/html/rfc7234#section-4.3.4 - we add a
custom header that will only be present in cache hits, that can tell the
frontend to ignore these.
This commit is contained in:
Sean McGivern 2018-04-17 11:50:27 +01:00
parent a18363e48e
commit d77db0adbd
2 changed files with 14 additions and 18 deletions

View File

@ -10,29 +10,25 @@ export default class PerformanceBarService {
}
static registerInterceptor(peekUrl, callback) {
vueResourceInterceptor = (request, next) => {
next(response => {
const requestId = response.headers['x-request-id'];
const requestUrl = response.url;
if (requestUrl !== peekUrl && requestId) {
callback(requestId, requestUrl);
}
});
};
Vue.http.interceptors.push(vueResourceInterceptor);
return axios.interceptors.response.use(response => {
const interceptor = response => {
const requestId = response.headers['x-request-id'];
const requestUrl = response.config.url;
// Get the request URL from response.config for Axios, and response for
// Vue Resource.
const requestUrl = (response.config || response).url;
const cachedResponse = response.headers['x-gitlab-from-cache'] === 'true';
if (requestUrl !== peekUrl && requestId) {
if (requestUrl !== peekUrl && requestId && !cachedResponse) {
callback(requestId, requestUrl);
}
return response;
});
};
vueResourceInterceptor = (request, next) => next(interceptor);
Vue.http.interceptors.push(vueResourceInterceptor);
return axios.interceptors.response.use(interceptor);
}
static removeInterceptor(interceptor) {

View File

@ -50,7 +50,7 @@ module Gitlab
status_code = Gitlab::PollingInterval.polling_enabled? ? 304 : 429
[status_code, { 'ETag' => etag }, []]
[status_code, { 'ETag' => etag, 'X-Gitlab-From-Cache' => 'true' }, []]
end
def track_cache_miss(if_none_match, cached_value_present, route)