You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@hc.apache.org by "Francois-Xavier Bonnet (JIRA)" <ji...@apache.org> on 2012/12/13 10:59:21 UTC
[jira] [Created] (HTTPCLIENT-1276) NullPointerException when 304
response updates a cache entry
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: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org