Uploaded image for project: 'HttpComponents HttpClient'
  1. HttpComponents HttpClient
  2. HTTPCLIENT-1276

NullPointerException when 304 response updates a cache entry

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Blocker
    • Resolution: Fixed
    • 4.2.2
    • 4.2.3
    • HttpCache
    • None

    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)

      Attachments

        1. HTTPCLIENT-1276.txt
          3 kB
          Francois-Xavier Bonnet
        2. HTTPCLIENT-1274_HTTPCLIENT-1276.txt
          6 kB
          Francois-Xavier Bonnet

        Activity

          People

            Unassigned Unassigned
            fx.bonnet Francois-Xavier Bonnet
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: