Francois-Xavier Bonnet created HTTPCLIENT-1276:
--------------------------------------------------

             Summary: NullPointerException when 304 response updates a cache 
entry
                 Key: HTTPCLIENT-1276
                 URL: https://issues.apache.org/jira/browse/HTTPCLIENT-1276
             Project: HttpComponents HttpClient
          Issue Type: Bug
          Components: Cache
    Affects Versions: 4.2.2, Snapshot
            Reporter: Francois-Xavier Bonnet
            Priority: Blocker


When sending a conditional request and the cache entry does not have an entity, 
CachingHttpClient throws a NullPointerException.

To reproduce :
- send a first conditional If-None-Match request and receive a first 304 that 
generates a cache entry with no entity
- send a second conditional request and receive another 304

When updating the cache entry, CachingHttpClient tries to copy the entity of 
the existing cache entry without testing if it is null.

Here is a test to reproduce :
        @Test
        public void testNotModifiedResponseUpdatesCacheEntryWhenNoEntity()
                        throws Exception {

                Date now = new Date();

                impl = new CachingExec(mockBackend, new 
BasicHttpCache(),CacheConfig.DEFAULT);

                HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new 
HttpGet("http://foo.example.com/";));
                req1.addHeader("If-None-Match", "etag");

                HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new 
HttpGet("http://foo.example.com/";));
                req2.addHeader("If-None-Match", "etag");

                HttpResponse resp1 = new 
BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "Not 
modified");
                resp1.setHeader("Date", DateUtils.formatDate(now));
                resp1.setHeader("Cache-Control","max-age=0");
                resp1.setHeader("Etag", "etag");

                HttpResponse resp2 = new 
BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "Not 
modified");
                resp2.setHeader("Date", DateUtils.formatDate(now));
                resp2.setHeader("Cache-Control","max-age=0");
                resp1.setHeader("Etag", "etag");

                backendExpectsAnyRequestAndReturn(resp1);
                backendExpectsAnyRequestAndReturn(resp2);
                replayMocks();
                HttpResponse result1 = impl.execute(route, req1);
                HttpResponse result2 = impl.execute(route, req2);
                verifyMocks();

                assertEquals(HttpStatus.SC_NOT_MODIFIED, 
result1.getStatusLine().getStatusCode());
                assertEquals("etag", result1.getFirstHeader("Etag").getValue());
                assertEquals(HttpStatus.SC_NOT_MODIFIED, 
result2.getStatusLine().getStatusCode());
                assertEquals("etag", result2.getFirstHeader("Etag").getValue());
        }

And here is what you get:
java.lang.NullPointerException
        at 
org.apache.http.impl.client.cache.HeapResourceFactory.copy(HeapResourceFactory.java:73)
        at 
org.apache.http.impl.client.cache.CacheEntryUpdater.updateCacheEntry(CacheEntryUpdater.java:90)
        at 
org.apache.http.impl.client.cache.BasicHttpCache.updateCacheEntry(BasicHttpCache.java:214)
        at 
org.apache.http.impl.client.cache.CachingExec.revalidateCacheEntry(CachingExec.java:752)
        at 
org.apache.http.impl.client.cache.CachingExec.revalidateCacheEntry(CachingExec.java:318)
        at 
org.apache.http.impl.client.cache.CachingExec.handleCacheHit(CachingExec.java:288)
        at 
org.apache.http.impl.client.cache.CachingExec.execute(CachingExec.java:266)
        at 
org.apache.http.impl.client.cache.CachingExec.execute(CachingExec.java:219)
        at 
org.apache.http.impl.client.cache.TestCachingExec.testNotModifiedResponseUpdatesHeadersInCacheWhenNoEntity(TestCachingExec.java:1591)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at 
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:592)
        at 
org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
        at 
org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
        at 
org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
        at 
org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
        at 
org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
        at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
        at 
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:69)
        at 
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:48)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:292)
        at 
org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
        at 
org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
        at 
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
        at 
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
        at 
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
        at 
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)




--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to