From b1f16b12c9e08c5cc034dadac484b651e145d6cd Mon Sep 17 00:00:00 2001 From: Shahar Talmi Date: Thu, 11 Sep 2014 15:02:30 +0300 Subject: [PATCH] fix(http): preserve config object when resolving from cache Closes #9004 --- src/ng/http.js | 6 ++++-- test/ng/httpSpec.js | 52 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/src/ng/http.js b/src/ng/http.js index d269ac83faec..3a73a137c0e2 100644 --- a/src/ng/http.js +++ b/src/ng/http.js @@ -1027,8 +1027,7 @@ function $HttpProvider() { if (isDefined(cachedResp)) { if (isPromiseLike(cachedResp)) { // cached request has already been sent, but there is no response yet - cachedResp.then(removePendingReq, removePendingReq); - return cachedResp; + cachedResp.then(resolvePromiseWithResult, resolvePromiseWithResult); } else { // serving from cache if (isArray(cachedResp)) { @@ -1106,6 +1105,9 @@ function $HttpProvider() { }); } + function resolvePromiseWithResult(result) { + resolvePromise(result.data, result.status, shallowCopy(result.headers()), result.statusText); + } function removePendingReq() { var idx = $http.pendingRequests.indexOf(config); diff --git a/test/ng/httpSpec.js b/test/ng/httpSpec.js index ebc46c8dea51..d388576f1e68 100644 --- a/test/ng/httpSpec.js +++ b/test/ng/httpSpec.js @@ -1352,6 +1352,24 @@ describe('$http', function() { })); + it('should not share the pending cached headers object instance', inject(function($rootScope) { + var firstResult; + callback.andCallFake(function(result) { + expect(result.headers()).toEqual(firstResult.headers()); + expect(result.headers()).not.toBe(firstResult.headers()); + }); + + $httpBackend.expect('GET', '/url').respond(200, 'content', {'content-encoding': 'gzip', 'server': 'Apache'}); + $http({method: 'GET', url: '/url', cache: cache}).then(function(result) { + firstResult = result; + }); + $http({method: 'GET', url: '/url', cache: cache}).then(callback); + $httpBackend.flush(); + + expect(callback).toHaveBeenCalledOnce(); + })); + + it('should cache status code as well', inject(function($rootScope) { doFirstCacheRequest('GET', 201); callback.andCallFake(function(r, status, h) { @@ -1381,6 +1399,40 @@ describe('$http', function() { }); + it('should preserve config object when resolving from cache', function() { + $httpBackend.expect('GET', '/url').respond(200, 'content'); + $http({method: 'GET', url: '/url', cache: cache, headers: {foo: 'bar'}}); + $httpBackend.flush(); + + $http({method: 'GET', url: '/url', cache: cache, headers: {foo: 'baz'}}).then(callback); + $rootScope.$digest(); + + expect(callback.mostRecentCall.args[0].config.headers.foo).toBe('baz'); + }); + + + it('should preserve config object when resolving from pending cache', function() { + $httpBackend.expect('GET', '/url').respond(200, 'content'); + $http({method: 'GET', url: '/url', cache: cache, headers: {foo: 'bar'}}); + + $http({method: 'GET', url: '/url', cache: cache, headers: {foo: 'baz'}}).then(callback); + $httpBackend.flush(); + + expect(callback.mostRecentCall.args[0].config.headers.foo).toBe('baz'); + }); + + + it('should preserve config object when rejecting from pending cache', function() { + $httpBackend.expect('GET', '/url').respond(404, 'content'); + $http({method: 'GET', url: '/url', cache: cache, headers: {foo: 'bar'}}); + + $http({method: 'GET', url: '/url', cache: cache, headers: {foo: 'baz'}}).catch(callback); + $httpBackend.flush(); + + expect(callback.mostRecentCall.args[0].config.headers.foo).toBe('baz'); + }); + + it('should allow the cached value to be an empty string', function() { cache.put('/abc', '');