[
https://issues.apache.org/jira/browse/HTTPCLIENT-1276?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Francois-Xavier Bonnet updated HTTPCLIENT-1276:
-----------------------------------------------
Description:
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)
was:
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)
> 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)
--
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]