You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2010/04/30 23:00:10 UTC

svn commit: r939814 [1/6] - in /httpcomponents/httpclient/trunk: ./ httpclient-cache/ httpclient-cache/src/ httpclient-cache/src/main/ httpclient-cache/src/main/java/ httpclient-cache/src/main/java/org/ httpclient-cache/src/main/java/org/apache/ httpcl...

Author: olegk
Date: Fri Apr 30 21:00:08 2010
New Revision: 939814

URL: http://svn.apache.org/viewvc?rev=939814&view=rev
Log:
HTTPCLIENT-427: HTTP caching support

Contributed by Joe Campbell, David Cleaver, David Mays, Jon Moore, Brad Spenla (Comcast Corporation)

Added:
    httpcomponents/httpclient/trunk/httpclient-cache/
    httpcomponents/httpclient/trunk/httpclient-cache/pom.xml
    httpcomponents/httpclient/trunk/httpclient-cache/src/
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCache.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheEntrySerializer.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheOperationException.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheUpdateCallback.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/BasicHttpCache.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/CacheEntry.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/CacheEntryGenerator.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/CacheEntryUpdater.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/CacheInvalidator.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/CacheableRequestPolicy.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/CachedHttpResponseGenerator.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/CachedResponseSuitabilityChecker.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/CachingHttpClient.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/CombinedInputStream.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/ConditionalRequestBuilder.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/DefaultCacheEntrySerializer.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/HeaderConstants.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/OptionsHttp11Response.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/RequestProtocolCompliance.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/RequestProtocolError.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/ResponseCachingPolicy.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/ResponseProtocolCompliance.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/SizeLimitedResponseReader.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/URIExtractor.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/client/
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/client/cache/
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/client/cache/impl/
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/client/cache/impl/Counter.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/client/cache/impl/DoNotTestProtocolRequirements.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/client/cache/impl/HttpTestUtils.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/client/cache/impl/RequestEquivalent.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/client/cache/impl/Serializer.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/client/cache/impl/TestCacheEntry.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/client/cache/impl/TestCacheEntryGenerator.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/client/cache/impl/TestCacheEntryUpdater.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/client/cache/impl/TestCacheInvalidator.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/client/cache/impl/TestCacheableRequestPolicy.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/client/cache/impl/TestCachedHttpResponseGenerator.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/client/cache/impl/TestCachedResponseSuitabilityChecker.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/client/cache/impl/TestCachingHttpClient.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/client/cache/impl/TestCombinedInputStream.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/client/cache/impl/TestConditionalRequestBuilder.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/client/cache/impl/TestDefaultCacheEntrySerializer.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/client/cache/impl/TestProtocolDeviations.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/client/cache/impl/TestProtocolRequirements.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/client/cache/impl/TestResponseCache.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/client/cache/impl/TestResponseCachingPolicy.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/client/cache/impl/TestSizeLimitedResponseReader.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/client/cache/impl/TestURIExtractor.java
Modified:
    httpcomponents/httpclient/trunk/RELEASE_NOTES.txt
    httpcomponents/httpclient/trunk/pom.xml

Modified: httpcomponents/httpclient/trunk/RELEASE_NOTES.txt
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/RELEASE_NOTES.txt?rev=939814&r1=939813&r2=939814&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/RELEASE_NOTES.txt (original)
+++ httpcomponents/httpclient/trunk/RELEASE_NOTES.txt Fri Apr 30 21:00:08 2010
@@ -1,75 +1,77 @@
 Release 4.1 ALPHA2
 -------------------
+* [HTTPCLIENT-427] HTTP caching support
+  Contributed by Joe Campbell, David Cleaver, David Mays, Jon Moore, Brad Spenla
 
-* Dropped dependency on Mime4j for HttpMime. 
+* Dropped dependency on Mime4j for HttpMime.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
-* Extended SSLSocketFactory with a mechanism to bypass the standard certificate 
-  trust verification (primarily to simplify dealing with self-signed 
-  certificates) 
+* Extended SSLSocketFactory with a mechanism to bypass the standard certificate
+  trust verification (primarily to simplify dealing with self-signed
+  certificates)
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
-* [HTTPCLIENT-916] UsernamePasswordCredentials, NTUserPrincipal, 
+* [HTTPCLIENT-916] UsernamePasswordCredentials, NTUserPrincipal,
   BasicClientCookie, BasicClientCookie2 and BasicCookieStore made Serializable.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
 * [HTTPCLIENT-914] Upgraded Commons Codec dependency to version 1.4
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
-* [HTTPCLIENT-903] Use ConcurrentHashMap instead of [Linked]HashMap for 
-  thread-safety. Improve performance of AuthSchemeRegistry, CookieSpecRegistry 
+* [HTTPCLIENT-903] Use ConcurrentHashMap instead of [Linked]HashMap for
+  thread-safety. Improve performance of AuthSchemeRegistry, CookieSpecRegistry
   and SchemeRegistry classes.
   Contributed by Sebastian Bazley <sebb at apache.org>
-  
+
 * [HTTPCLIENT-902] HttpRequestRetryHandler not called on I/O exceptions
   thrown when opening a new connection.
-  Contributed by Olivier Lamy <olamy at apache.org> and 
+  Contributed by Olivier Lamy <olamy at apache.org> and
   Oleg Kalnichevski <olegk at apache.org>
 
 Release 4.1 ALPHA1
 -------------------
 
-HttpClient 4.1 ALPHA1 builds on the stable 4.0 release and adds several 
+HttpClient 4.1 ALPHA1 builds on the stable 4.0 release and adds several
 functionality improvements and new features.
 
 * Simplified configuration of connection managers.
 
-* Persistence of authentication data between request executions within 
+* Persistence of authentication data between request executions within
   the same execution context.
 
 * Support for SPNEGO/Kerberos authentication scheme
 
-* Support for transparent content encoding. Please note transparent content 
+* Support for transparent content encoding. Please note transparent content
   encoding is not enabled per default in order to avoid conflicts with
   already existing custom content encoding solutions.
 
-* 5 to 10% performance increase due to elimination of unnecessary Log object 
+* 5 to 10% performance increase due to elimination of unnecessary Log object
   lookups by short-lived components.
 
 Please note all methods and classes added in this release and marked as
 4.1 are API unstable and can change in the future 4.1 ALPHA releases.
-  
+
 Changelog
 -------------------
 
 * [HTTPCLIENT-889] 'expect: continue' handshake disabled per default.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
-* [HTTPCLIENT-862] Extended client's redirect handling interface to allow 
+* [HTTPCLIENT-862] Extended client's redirect handling interface to allow
   control of the content of the redirect.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
-* [HTTPCLIENT-872] HttpClient can now persist authentication data between request 
+* [HTTPCLIENT-872] HttpClient can now persist authentication data between request
   executions as long as they share the same execution context. It has also become
-  much easier to make HttpClient authenticate preemptively by pre-populating 
+  much easier to make HttpClient authenticate preemptively by pre-populating
   authentication data cache.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
 * [HTTPCLIENT-883] SO_TIMEOUT is not reset on persistent (re-used) connections.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
-* [HTTPCLIENT-832] Distinguish cookie format errors from violations of 
-  restrictions imposed by a cookie specification. In the latter case 
+* [HTTPCLIENT-832] Distinguish cookie format errors from violations of
+  restrictions imposed by a cookie specification. In the latter case
   CookieRestrictionViolationException will be thrown.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
@@ -77,16 +79,16 @@ Changelog
   Contributed by Matthew Stevenson <mavricknzwork at yahoo.com>
 
 * Simplified configuration of connection managers. Total connection maximum
-  and maximum connection per route limits can be set using methods of 
+  and maximum connection per route limits can be set using methods of
   the class instead of HTTP parameters.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
-* Added parameters to define the order of preference for supported auth 
+* Added parameters to define the order of preference for supported auth
   schemes for target host and proxy authentication.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
-* [HTTPCLIENT-875] DefaultClientConnectionOperator#openConnection doesn't 
-  update the connection state if the connection socket changed after 
+* [HTTPCLIENT-875] DefaultClientConnectionOperator#openConnection doesn't
+  update the connection state if the connection socket changed after
   the call to SocketFactory#connectSocket().
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
@@ -96,8 +98,8 @@ Changelog
 Release 4.0.1
 -------------------
 
-This is a bug fix release that addresses a number of issues discovered since 
-the previous stable release. None of the fixed bugs is considered critical. 
+This is a bug fix release that addresses a number of issues discovered since
+the previous stable release. None of the fixed bugs is considered critical.
 Most notably this release eliminates eliminates dependency on JCIP annotations.
 
 This release is also expected to improve performance by 5 to 10% due to
@@ -106,33 +108,33 @@ elimination of unnecessary Log object lo
 Changelog
 -------------------
 
-* [HTTPCLIENT-895] Eliminated Log lookups in short lived objects impairing 
+* [HTTPCLIENT-895] Eliminated Log lookups in short lived objects impairing
   performance.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
-* [HTTPCLIENT-885] URLEncodedUtils now correctly parses form-url-encoded 
+* [HTTPCLIENT-885] URLEncodedUtils now correctly parses form-url-encoded
   entities that specify a charset.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
-* [HTTPCLIENT-884] UrlEncodedFormEntity now sets charset on the Content-Type 
+* [HTTPCLIENT-884] UrlEncodedFormEntity now sets charset on the Content-Type
   header.
-  Contributed by Jared Jacobs <jmjacobs at cs.stanford.edu>  
-  
+  Contributed by Jared Jacobs <jmjacobs at cs.stanford.edu>
+
 * [HTTPCLIENT-883] SO_TIMEOUT is not reset on persistent (re-used) connections.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
-* [HTTPCLIENT-882] Auth state is now correctly updated if a successful NTLM 
-  authentication results in a redirect. This is a minor bug as HttpClient 
+* [HTTPCLIENT-882] Auth state is now correctly updated if a successful NTLM
+  authentication results in a redirect. This is a minor bug as HttpClient
   manages to recover from the problem automatically.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
 * [HTTPCLIENT-881] Fixed race condition in AbstractClientConnAdapter that makes
   it possible for an aborted connection to be returned to the pool.
-  Contributed by Tim Boemker <tboemker at elynx.com> and 
+  Contributed by Tim Boemker <tboemker at elynx.com> and
   Oleg Kalnichevski <olegk at apache.org>
 
 * [HTTPCLIENT-866] Removed dependency on jcip-annotations.jar.
-  Contributed by Oleg Kalnichevski <olegk at apache.org> 
+  Contributed by Oleg Kalnichevski <olegk at apache.org>
   and Sebastian Bazley <sebb at apache.org>
 
 
@@ -148,42 +150,42 @@ a major code overhaul and breaking API c
 Architectural changes
 ---------------------
 
-* Redesign of the HttpClient internals addressing all known major 
+* Redesign of the HttpClient internals addressing all known major
   architectural shortcomings of the 3.x codeline.
 
 * Cleaner, more flexible and expressive API.
 
 * More modular structure.
 
-* Better performance and smaller memory footprint due to a more efficient HTTP 
-  transport based on HttpCore. 
+* Better performance and smaller memory footprint due to a more efficient HTTP
+  transport based on HttpCore.
 
-* Implementation of cross-cutting HTTP protocol aspects through protocol 
+* Implementation of cross-cutting HTTP protocol aspects through protocol
   interceptors.
 
 * Improved connection management, better handling of persistent connections,
   support for stateful connections
 
-* Pluggable redirect and authentication handlers.   
+* Pluggable redirect and authentication handlers.
 
-* Improved support for sending requests via a proxy or a chain of proxies 
+* Improved support for sending requests via a proxy or a chain of proxies
 
-* More flexible SSL context customization 
+* More flexible SSL context customization
 
-* Reduced intermediate garbage in the process of generating HTTP requests 
-  and parsing HTTP responses 
+* Reduced intermediate garbage in the process of generating HTTP requests
+  and parsing HTTP responses
 
 
 Important notes
 -------------------
 
-* Future releases of HttpMime module may be binary incompatible with this 
+* Future releases of HttpMime module may be binary incompatible with this
   release due to possible API changes in Apache Mime4J. Apache Mime4J is
   still being actively developed and its API is considered unstable.
-  
+
 * HttpClient 4.0 is not fully binary compatible with 4.0 BETA1 release.
   Some protected variables in connection management class have been
-  made final in order to help ensure their thread safety: 
+  made final in order to help ensure their thread safety:
 
     org.apache.http.conn.BasicEofSensorWatcher#attemptReuse
     org.apache.http.conn.BasicEofSensorWatcher#managedConn
@@ -195,20 +197,20 @@ Important notes
     org.apache.http.impl.conn.SingleClientConnManager#schemeRegistry
     org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager#connOperator
     org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager#schemeRegistry
-    
 
-Bug fixes since 4.0 BETA2 release 
+
+Bug fixes since 4.0 BETA2 release
 -------------------
 
-* [HTTPCLIENT-861] URIUtils#resolve is now compatible with all examples given 
+* [HTTPCLIENT-861] URIUtils#resolve is now compatible with all examples given
   in RFC 3986.
   Contributed by Johannes Koch <johannes.koch at fit.fraunhofer.de>
 
-* [HTTPCLIENT-860] HttpClient no longer converts redirects of PUT/POST to GET 
+* [HTTPCLIENT-860] HttpClient no longer converts redirects of PUT/POST to GET
   for status codes 301, 302, 307, as required by the HTTP spec.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
-* [HTTPCLIENT-859] CookieIdentityComparator now takes path attribute into 
+* [HTTPCLIENT-859] CookieIdentityComparator now takes path attribute into
   consideration when comparing cookies.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
@@ -219,20 +221,20 @@ Bug fixes since 4.0 BETA2 release 
   a different host.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
-* [HTTPCLIENT-841] Removed automatic connection release using garbage collection 
+* [HTTPCLIENT-841] Removed automatic connection release using garbage collection
   due to a memory leak.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
-* [HTTPCLIENT-853] Fixed bug causing invalid cookie origin port to be selected 
-  when the target is accessed on the default port and the connection is 
+* [HTTPCLIENT-853] Fixed bug causing invalid cookie origin port to be selected
+  when the target is accessed on the default port and the connection is
   established via a proxy.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
-* [HTTPCLIENT-852] Fixed bug causing automatically retried redirects fail with 
-  CircularRedirectException.  
+* [HTTPCLIENT-852] Fixed bug causing automatically retried redirects fail with
+  CircularRedirectException.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
-* Fixed problem with the default HTTP response parser failing to handle garbage 
+* Fixed problem with the default HTTP response parser failing to handle garbage
   preceding a valid HTTP response.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
@@ -240,12 +242,12 @@ Bug fixes since 4.0 BETA2 release 
   request failed.
   Contributed by Sam Berlin <sberlin at apache.org>
 
-* [HTTPCLIENT-837] Fixed problem with the wire log skipping zero byte values 
+* [HTTPCLIENT-837] Fixed problem with the wire log skipping zero byte values
   if read one byte at a time.
   Contributed by Kirill Safonov <ksafonov at swiftteams.com>
 
-* [HTTPCLIENT-823] 'http.conn-manager.max-total' parameter can be adjusted 
-  dynamically. However, the size of existing connection pools per route, 
+* [HTTPCLIENT-823] 'http.conn-manager.max-total' parameter can be adjusted
+  dynamically. However, the size of existing connection pools per route,
   once allocated, will not be adjusted.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
@@ -260,20 +262,20 @@ Bug fixes since 4.0 BETA2 release 
 Release 4.0 beta 2
 -------------------
 
-BETA2 is a maintenance release, which addresses a number of issues 
-discovered since the previous release. 
+BETA2 is a maintenance release, which addresses a number of issues
+discovered since the previous release.
 
-The only significant new feature is an addition of an OSGi compliant 
+The only significant new feature is an addition of an OSGi compliant
 bundle combining HttpClient and HttpMime jars.
 
 All upstream projects are strongly encouraged to upgrade.
 
-* Fixed NPE in DefaultRequestDirector thrown when retrying a failed 
-  request over a proxied connection. 
+* Fixed NPE in DefaultRequestDirector thrown when retrying a failed
+  request over a proxied connection.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
-* [HTTPCLIENT-803] Fixed bug in SSL host verifier implementations 
-  causing the SSL certificate to be rejected as invalid if the connection 
+* [HTTPCLIENT-803] Fixed bug in SSL host verifier implementations
+  causing the SSL certificate to be rejected as invalid if the connection
   is established using an IP address.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
@@ -282,32 +284,32 @@ All upstream projects are strongly encou
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
 * DigestScheme can use an arbitrary digest algorithm requested by the
-  target server (such as SHA) as long as this algorithm is supported by 
-  the Java runtime.     
+  target server (such as SHA) as long as this algorithm is supported by
+  the Java runtime.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
-* Fixed parsing and validation of RFC2109 compliant Set-Cookie headers 
-  by the Best-Match cookie spec.     
+* Fixed parsing and validation of RFC2109 compliant Set-Cookie headers
+  by the Best-Match cookie spec.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
 * Fixed bug that can cause a managed connection to be returned from the
-  pool in an inconsistent state.     
+  pool in an inconsistent state.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
 
 4.0 Beta 1
 -------------------
 
-BETA1 release brings yet another round of API enhancements and 
+BETA1 release brings yet another round of API enhancements and
 improvements in the area of connection management. Among the most notable
-ones is the capability to handle stateful connections such as persistent 
+ones is the capability to handle stateful connections such as persistent
 NTLM connections and private key authenticated SSL connections.
 
-This is the first API stable release of HttpClient 4.0. All further 
+This is the first API stable release of HttpClient 4.0. All further
 releases in the 4.0 code line will maintain API compatibility with this
 release.
 
-There has been a number of important bug fixes since ALPHA4. All upstream 
+There has been a number of important bug fixes since ALPHA4. All upstream
 projects are encouraged to upgrade to the latest release.
 
 Please note HttpClient currently provides only limited support for NTLM
@@ -318,7 +320,7 @@ authentication. For details please see N
 Changelog:
 -------------------
 
-* [HTTPCLIENT-790] Protocol interceptors are now correctly invoked when 
+* [HTTPCLIENT-790] Protocol interceptors are now correctly invoked when
   executing CONNECT methods.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
@@ -356,8 +358,8 @@ Changelog:
 
 * Resolved a long standing problem with HttpClient not taking into account
   the user context when pooling / re-using connections. HttpClient now
-  correctly handles stateful / user specific connections such as persistent 
-  NTLM connections and SSL connections with client side authentication. 
+  correctly handles stateful / user specific connections such as persistent
+  NTLM connections and SSL connections with client side authentication.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
 * [HTTPCLIENT-773] Improved handling of the 'expires' attribute by the
@@ -376,14 +378,14 @@ Changelog:
 Release 4.0 Alpha 4
 -------------------
 
-ALPHA4 marks the completion of the overhaul of the connection management 
-code in HttpClient. All known shortcomings of the old HttpClient 3.x 
+ALPHA4 marks the completion of the overhaul of the connection management
+code in HttpClient. All known shortcomings of the old HttpClient 3.x
 connection management API have been addressed.
 
-NTLM authentication remains the only missing major feature in the new 
+NTLM authentication remains the only missing major feature in the new
 codeline that prevents us from moving awards the API freeze.
 
-There has been a number of important bug fixes since ALPHA3. All upstream 
+There has been a number of important bug fixes since ALPHA3. All upstream
 projects are encouraged to upgrade to the latest release.
 
 -------------------
@@ -398,19 +400,19 @@ HttpClient 3.x features that have NOT ye
 Changelog:
 -------------------
 
-* [HTTPCLIENT-765] String.toLowerCase() / toUpperCase() should specify 
+* [HTTPCLIENT-765] String.toLowerCase() / toUpperCase() should specify
   Locale.ENGLISH
   Contributed by Sebastian Bazley <sebb at apache.org>
 
 * [HTTPCLIENT-769] Do not pool connection marked non-reusable.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
-* [HTTPCLIENT-763] Fixed problem with AbstractClientConnAdapter#abortConnection() 
-  not releasing the connection if called from the main execution thread while 
+* [HTTPCLIENT-763] Fixed problem with AbstractClientConnAdapter#abortConnection()
+  not releasing the connection if called from the main execution thread while
   there is no blocking I/O operation.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
-* [HTTPCLIENT-652] Added optional state attribute to managed client connections. 
+* [HTTPCLIENT-652] Added optional state attribute to managed client connections.
   This enables connection managers to correctly handle stateful connections.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
@@ -420,15 +422,15 @@ Changelog:
 * [HTTPCLIENT-753] Class Scheme and related classes moved to a separate package
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
-* [HTTPCLIENT-757] Improved request wrapping in the DefaultClientRequestDirector. 
-  This also fixed the problem with the default proxy set at the client level 
-  having no effect. 
+* [HTTPCLIENT-757] Improved request wrapping in the DefaultClientRequestDirector.
+  This also fixed the problem with the default proxy set at the client level
+  having no effect.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
 * [HTTPCLIENT-734] Request abort will unblock the thread waiting for a connection
   Contributed by Sam Berlin <sberlin at gmail.com>
 
-* [HTTPCLIENT-759] Ensure release of connections back to the connection manager 
+* [HTTPCLIENT-759] Ensure release of connections back to the connection manager
   on exceptions.
   Contributed by Sam Berlin <sberlin at gmail.com>
 
@@ -448,18 +450,18 @@ Changelog:
 Release 4.0 Alpha 3
 -------------------
 
-ALPHA3 release brings another round of API refinements and improvements in 
-functionality. As of this release HttpClient requires Java 5 compatible 
+ALPHA3 release brings another round of API refinements and improvements in
+functionality. As of this release HttpClient requires Java 5 compatible
 runtime environment and takes full advantage of generics and new concurrency
-primitives.     
+primitives.
 
-This release also introduces new default cookie policy that selects a cookie 
-specification depending on the format of cookies sent by the target host. 
-It is no longer necessary to know beforehand what kind of HTTP cookie support 
-the target host provides. HttpClient is now able to pick up either a lenient 
+This release also introduces new default cookie policy that selects a cookie
+specification depending on the format of cookies sent by the target host.
+It is no longer necessary to know beforehand what kind of HTTP cookie support
+the target host provides. HttpClient is now able to pick up either a lenient
 or a strict cookie policy depending on the compliance level of the target host.
 
-Another notable improvement is a completely reworked support for multipart 
+Another notable improvement is a completely reworked support for multipart
 entities based on Apache mime4j library.
 
 -------------------
@@ -499,10 +501,10 @@ Changelog:
   Contributed by Roland Weber <rolandw at apache.org>
 
 * [HTTPCLIENT-730] Fixed rewriting of URIs containing escaped characters
-  Contributed by Sam Berlin <sberlin at gmail.com> and 
+  Contributed by Sam Berlin <sberlin at gmail.com> and
   Oleg Kalnichevski <olegk at apache.org>
- 
-* [HTTPCLIENT-667] Added 'Meta' cookie policy that selects a cookie 
+
+* [HTTPCLIENT-667] Added 'Meta' cookie policy that selects a cookie
   specification depending on the format of the cookie(s).
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
@@ -530,7 +532,7 @@ Changelog:
 * [HTTPCLIENT-705] Fixed incorrect handling of URIs with null path component.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
-* [HTTPCLIENT-688] HttpOptions#getAllowedMethods can now handle multiple 
+* [HTTPCLIENT-688] HttpOptions#getAllowedMethods can now handle multiple
   Allow headers.
   Contributed by Andrea Selva <selva.andre at gmail.com>
 
@@ -539,10 +541,10 @@ Changelog:
 Release 4.0 Alpha 2
 -------------------
 
-ALPHA2 release is another milestone in the redesign of HttpClient. It includes 
-a number of improvements since ALPHA1, among which are improved connection 
+ALPHA2 release is another milestone in the redesign of HttpClient. It includes
+a number of improvements since ALPHA1, among which are improved connection
 pooling, support for proxy chains, redesigned HTTP state and authentication
-credentials management API, improved RFC 2965 cookie specification.   
+credentials management API, improved RFC 2965 cookie specification.
 
 -------------------
 
@@ -550,14 +552,14 @@ HttpClient 3.x features that have NOT ye
 -------------------
 * NTLM authentication scheme
 
-* Support for multipart MIME coded entities  
+* Support for multipart MIME coded entities
 
 -------------------
 
 Changelog
 -------------------
 
-* [HTTPCLIENT-698] Resolve non-absolute redirect URIs relative to 
+* [HTTPCLIENT-698] Resolve non-absolute redirect URIs relative to
   the request URI
   Contributed by Johannes Koch <johannes.koch at fit.fraunhofer.de>
 
@@ -571,7 +573,7 @@ Changelog
 * [HTTPCLIENT-689] stackable parameters in AbstractHttpClient
   Contributed by Roland Weber <rolandw at apache.org>
 
-* [HTTPCLIENT-477] Use distinct instances of the authentication handler 
+* [HTTPCLIENT-477] Use distinct instances of the authentication handler
   interface for authentication with target and proxy hosts
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
@@ -600,7 +602,7 @@ Changelog
 * [HTTPCLIENT-674] use org.apache.http.util.VersionInfo instead of a local one
   Contributed by Roland Weber <rolandw at apache.org>
 
-* [HTTPCLIENT-666] Replaced HttpState with CredentialsProvier and CookieStore interfaces 
+* [HTTPCLIENT-666] Replaced HttpState with CredentialsProvier and CookieStore interfaces
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
 * [HTTPCORE-100] revised HttpContext hierarchy
@@ -632,29 +634,29 @@ Architectural changes
 * Redesign of the HttpClient internals addressing all known
   major architectural shortcomings of the 3.x codeline
 
-* Cleaner, more flexible and expressive API   
+* Cleaner, more flexible and expressive API
 
-* Better performance and smaller memory footprint due to a more 
-  efficient HTTP transport based on HttpCore. HttpClient 4.0 is 
+* Better performance and smaller memory footprint due to a more
+  efficient HTTP transport based on HttpCore. HttpClient 4.0 is
   expected to be 10% to 25% faster than HttpClient 3.x codeline
 
-* More modular structure   
+* More modular structure
 
-* Pluggable redirect and authentication handlers   
+* Pluggable redirect and authentication handlers
 
 * Support for protocol incerceptors
 
-* Improved connection management 
+* Improved connection management
 
-* Improved support for sending requests via a proxy or a chain of 
-  proxies 
+* Improved support for sending requests via a proxy or a chain of
+  proxies
 
 * Improved handling redirects of entity enclosing requests
 
-* More flexible SSL context customization 
+* More flexible SSL context customization
 
 * Reduced intermediate garbage in the process of
-  generating HTTP requests and parsing HTTP responses 
+  generating HTTP requests and parsing HTTP responses
 
 -------------------
 
@@ -664,7 +666,7 @@ HttpClient 3.x features that have NOT ye
 
 * RFC2965 cookie policy (Cookie2)
 
-* Support for multipart MIME coded entities  
+* Support for multipart MIME coded entities
 
 -------------------
 
@@ -691,11 +693,11 @@ of the source code repository would have
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
 * [HTTPCLIENT-63] Support for pluggable redirect and authentication handlers
-  Long standing architectural problem. Issue opened on 15/Jul/2002. 
+  Long standing architectural problem. Issue opened on 15/Jul/2002.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
 * [HTTPCLIENT-245] Fixed redirect handling. HttpClient can now automatically
-  handle redirects of entity enclosing requests. 
+  handle redirects of entity enclosing requests.
   Long standing architectural problem. Issue opened on 14/Jul/2003.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 

Added: httpcomponents/httpclient/trunk/httpclient-cache/pom.xml
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/pom.xml?rev=939814&view=auto
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/pom.xml (added)
+++ httpcomponents/httpclient/trunk/httpclient-cache/pom.xml Fri Apr 30 21:00:08 2010
@@ -0,0 +1,218 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+   ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License.
+   ====================================================================
+
+   This software consists of voluntary contributions made by many
+   individuals on behalf of the Apache Software Foundation.  For more
+   information on the Apache Software Foundation, please see
+   <http://www.apache.org />.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.httpcomponents</groupId>
+    <artifactId>httpcomponents-client</artifactId>
+    <version>4.1-alpha2-SNAPSHOT</version>
+  </parent>
+  <artifactId>httpclient-cache</artifactId>
+  <name>HttpClient Cache</name>
+  <description>
+   HttpComponents HttpClient - Cache
+  </description>
+  <url>http://hc.apache.org/httpcomponents-client</url>
+  <packaging>jar</packaging>  
+
+  <licenses>
+    <license>
+      <name>Apache License</name>
+      <url>../LICENSE.txt</url>
+      <distribution>repo</distribution>
+    </license>
+  </licenses>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.httpcomponents</groupId>
+      <artifactId>httpclient</artifactId>
+      <version>${project.version}</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>commons-logging</groupId>
+      <artifactId>commons-logging</artifactId>
+      <version>${commons-logging.version}</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>${junit.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.easymock</groupId>
+      <artifactId>easymock</artifactId>
+      <version>${easymock.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.easymock</groupId>
+      <artifactId>easymockclassextension</artifactId>
+      <version>${easymock.version}</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+    <maven.compile.source>1.5</maven.compile.source>
+    <maven.compile.target>1.5</maven.compile.target>
+    <maven.compile.optimize>true</maven.compile.optimize>
+    <maven.compile.deprecation>true</maven.compile.deprecation>
+  </properties>
+
+  <build>
+    <resources>
+      <resource>
+        <directory>src/main/resources</directory>
+        <filtering>false</filtering>
+        <includes>
+            <include>META-INF/*</include>
+        </includes>
+      </resource>
+      <resource>
+        <directory>src/main/resources</directory>
+        <filtering>true</filtering>
+        <includes>
+            <include>**/*.properties</include>
+        </includes>
+      </resource>
+      <resource>
+        <directory>..</directory>
+        <targetPath>META-INF</targetPath>
+        <includes>
+          <include>LICENSE.txt</include>
+        </includes>
+      </resource>
+      <resource>
+        <directory>../src/main/resources</directory>
+        <targetPath>META-INF</targetPath>
+        <filtering>true</filtering>
+        <includes>
+          <include>NOTICE.txt</include>
+        </includes>
+      </resource>
+    </resources>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <configuration>
+          <source>${maven.compile.source}</source>
+          <target>${maven.compile.target}</target>
+          <optimize>${maven.compile.optimize}</optimize>
+          <showDeprecations>${maven.compile.deprecation}</showDeprecations>
+        </configuration>
+      </plugin>
+      <plugin>
+        <artifactId>maven-surefire-plugin</artifactId>
+      </plugin>
+      <plugin>
+        <artifactId>maven-jar-plugin</artifactId>
+        <configuration>
+          <archive>
+            <manifestEntries>
+              <Specification-Title>HttpComponents HttpMime</Specification-Title>
+              <Specification-Version>${project.version}</Specification-Version>
+              <Specification-Vendor>The Apache Software Foundation</Specification-Vendor>
+              <Implementation-Title>HttpComponents HttpMime</Implementation-Title>
+              <Implementation-Version>${project.version}</Implementation-Version>
+              <Implementation-Vendor>The Apache Software Foundation</Implementation-Vendor>
+              <Implementation-Vendor-Id>org.apache</Implementation-Vendor-Id>
+              <url>${project.url}</url>
+            </manifestEntries>
+          </archive>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>com.atlassian.maven.plugins</groupId>
+        <artifactId>maven-clover2-plugin</artifactId>
+        <configuration>
+          <flushPolicy>threaded</flushPolicy>
+          <flushInterval>100</flushInterval>
+          <targetPercentage>50%</targetPercentage>
+        </configuration>
+        <executions>
+          <execution>
+            <id>site</id>
+            <phase>pre-site</phase>
+            <goals>
+              <goal>instrument</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+
+  <reporting>
+    <plugins>
+
+      <plugin>
+        <artifactId>maven-javadoc-plugin</artifactId>
+        <configuration>
+          <source>1.5</source>
+          <links>
+            <link>http://java.sun.com/j2se/1.5.0/docs/api/</link>
+            <link>http://hc.apache.org/httpcomponents-core/httpcore/apidocs/</link>
+            <link>http://hc.apache.org/httpcomponents-client/httpclient/apidocs/</link>
+          </links>
+        </configuration>
+        <reportSets>
+          <reportSet>
+            <reports>
+              <report>javadoc</report>
+            </reports>
+          </reportSet>
+        </reportSets>
+      </plugin>
+
+      <plugin>
+        <groupId>com.atlassian.maven.plugins</groupId>
+        <artifactId>maven-clover2-plugin</artifactId>
+        <configuration>
+          <jdk>1.5</jdk>
+        </configuration>
+      </plugin>
+
+      <plugin>
+        <artifactId>maven-jxr-plugin</artifactId>
+      </plugin>
+
+      <plugin>
+        <artifactId>maven-surefire-report-plugin</artifactId>
+      </plugin>
+
+    </plugins>
+  </reporting>
+
+</project>

Added: httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCache.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCache.java?rev=939814&view=auto
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCache.java (added)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCache.java Fri Apr 30 21:00:08 2010
@@ -0,0 +1,43 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.http.client.cache;
+
+/**
+ * @since 4.1
+ */
+public interface HttpCache<E> {
+
+    void putEntry(String url, E entry) throws HttpCacheOperationException;
+
+    E getEntry(String url) throws HttpCacheOperationException;
+
+    void removeEntry(String url) throws HttpCacheOperationException;
+
+    void updateCacheEntry(
+            String url, HttpCacheUpdateCallback<E> callback) throws HttpCacheOperationException;
+
+}

Added: httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheEntrySerializer.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheEntrySerializer.java?rev=939814&view=auto
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheEntrySerializer.java (added)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheEntrySerializer.java Fri Apr 30 21:00:08 2010
@@ -0,0 +1,44 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.http.client.cache;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * Common operations for cache entry serialization and deserialization.
+ *
+ * @since 4.1
+ */
+public interface HttpCacheEntrySerializer<E> {
+
+    public void writeTo(E entry, OutputStream os) throws IOException;
+
+    public E readFrom(InputStream is) throws IOException;
+
+}
\ No newline at end of file

Added: httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheOperationException.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheOperationException.java?rev=939814&view=auto
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheOperationException.java (added)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheOperationException.java Fri Apr 30 21:00:08 2010
@@ -0,0 +1,56 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.http.client.cache;
+
+
+/**
+ * Exception to be thrown when an {@link HttpCache} encounters an error performing
+ * an caching operation.
+ *
+ * @since 4.1
+ */
+public class HttpCacheOperationException extends Exception {
+
+    private static final long serialVersionUID = 823573584868632876L;
+
+    public HttpCacheOperationException() {
+        super();
+    }
+
+    public HttpCacheOperationException(String message) {
+        super(message);
+    }
+
+    public HttpCacheOperationException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public HttpCacheOperationException(Throwable cause) {
+        super(cause);
+    }
+
+}
\ No newline at end of file

Added: httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheUpdateCallback.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheUpdateCallback.java?rev=939814&view=auto
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheUpdateCallback.java (added)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheUpdateCallback.java Fri Apr 30 21:00:08 2010
@@ -0,0 +1,46 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.http.client.cache;
+
+public interface HttpCacheUpdateCallback<E> {
+
+    /**
+     * Returns the new cache entry that should replace an existing one.
+     *
+     * @param existing
+     *            the cache entry current in-place in the cache, possibly
+     *            <code>null</code> if nonexistent
+     * @return CacheEntry the cache entry that should replace it, again,
+     *         possible <code>null</code>
+     * @throws HttpCacheOperationException
+     *             exception containing information about a failure in the cache
+     *
+     * @since 4.1
+     */
+    E getUpdatedEntry(E existing) throws HttpCacheOperationException;
+
+}
\ No newline at end of file

Added: httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/BasicHttpCache.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/BasicHttpCache.java?rev=939814&view=auto
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/BasicHttpCache.java (added)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/BasicHttpCache.java Fri Apr 30 21:00:08 2010
@@ -0,0 +1,103 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.http.client.cache.impl;
+
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.apache.http.client.cache.HttpCacheOperationException;
+import org.apache.http.client.cache.HttpCacheUpdateCallback;
+import org.apache.http.client.cache.HttpCache;
+
+/**
+ * Implements {@link HttpCache} using LinkedHashMap for backing store
+ * 
+ * @since 4.1
+ */
+public class BasicHttpCache implements HttpCache<CacheEntry> {
+
+    private LinkedHashMap<String, CacheEntry> baseMap = new LinkedHashMap<String, CacheEntry>(20,
+            0.75f, true) {
+
+        private static final long serialVersionUID = -7750025207539768511L;
+
+        protected boolean removeEldestEntry(Map.Entry<String, CacheEntry> eldest) {
+            return size() > maxEntries;
+        }
+    };
+
+    private Map<String, CacheEntry> syncMap;
+
+    private int maxEntries;
+
+    public BasicHttpCache(int maxEntries) {
+        this.maxEntries = maxEntries;
+        syncMap = Collections.synchronizedMap(baseMap);
+    }
+
+    /**
+     * Places a CacheEntry in the cache
+     *
+     * @param url
+     *            Url to use as the cache key
+     * @param entry
+     *            CacheEntry to place in the cache
+     */
+    public void putEntry(String url, CacheEntry entry) {
+        syncMap.put(url, entry);
+    }
+
+    /**
+     * Gets an entry from the cache, if it exists
+     *
+     * @param url
+     *            Url that is the cache key
+     * @return CacheEntry if one exists, or null for cache miss
+     */
+    public CacheEntry getEntry(String url) {
+        return syncMap.get(url);
+    }
+
+    /**
+     * Removes a CacheEntry from the cache
+     *
+     * @param url
+     *            Url that is the cache key
+     */
+    public void removeEntry(String url) {
+        syncMap.remove(url);
+    }
+
+    public synchronized void updateCacheEntry(
+            String url, 
+            HttpCacheUpdateCallback<CacheEntry> callback) throws HttpCacheOperationException {
+        CacheEntry existingEntry = syncMap.get(url);
+        CacheEntry updated = callback.getUpdatedEntry(existingEntry);
+        syncMap.put(url, updated);
+    }
+}

Added: httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/CacheEntry.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/CacheEntry.java?rev=939814&view=auto
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/CacheEntry.java (added)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/CacheEntry.java Fri Apr 30 21:00:08 2010
@@ -0,0 +1,416 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.http.client.cache.impl;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.http.Header;
+import org.apache.http.HeaderElement;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.ProtocolVersion;
+import org.apache.http.StatusLine;
+import org.apache.http.impl.cookie.DateParseException;
+import org.apache.http.impl.cookie.DateUtils;
+import org.apache.http.message.BasicHeader;
+
+/**
+ * Structure used to store an {@link HttpResponse} in a cache
+ *
+ * @since 4.1
+ */
+public class CacheEntry implements Serializable {
+
+    private static final long serialVersionUID = -6300496422359477413L;
+
+    public static final long MAX_AGE = 2147483648L;
+
+    private transient Header[] responseHeaders;
+    private byte[] body;
+    private ProtocolVersion version;
+    private int status;
+    private String reason;
+    private Date requestDate;
+    private Date responseDate;
+    private Set<String> variantURIs = new HashSet<String>();
+
+    /**
+     * Default constructor
+     */
+    public CacheEntry() {
+    }
+
+    /**
+     * @param requestDate
+     *            Date/time when the request was made (Used for age
+     *            calculations)
+     * @param responseDate
+     *            Date/time that the response came back (Used for age
+     *            calculations)
+     * @param response
+     *            original {@link HttpResponse}
+     * @param responseBytes
+     *            Byte array containing the body of the response
+     * @throws IOException
+     *             Does not attempt to handle IOExceptions
+     */
+    public CacheEntry(Date requestDate, Date responseDate, HttpResponse response,
+            byte[] responseBytes) throws IOException {
+        this.requestDate = requestDate;
+        this.responseDate = responseDate;
+        version = response.getProtocolVersion();
+        responseHeaders = response.getAllHeaders();
+        StatusLine sl = response.getStatusLine();
+        status = sl.getStatusCode();
+        reason = sl.getReasonPhrase();
+
+        body = responseBytes;
+    }
+
+    public void setProtocolVersion(ProtocolVersion version) {
+        this.version = version;
+    }
+
+    public ProtocolVersion getProtocolVersion() {
+        return version;
+    }
+
+    public String getReasonPhrase() {
+        return this.reason;
+    }
+
+    public int getStatusCode() {
+        return this.status;
+    }
+
+    public void setRequestDate(Date requestDate) {
+        this.requestDate = requestDate;
+    }
+
+    public Date getRequestDate() {
+        return requestDate;
+    }
+
+    public void setResponseDate(Date responseDate) {
+        this.responseDate = responseDate;
+    }
+
+    public Date getResponseDate() {
+        return this.responseDate;
+    }
+
+    public void setBody(byte[] body) {
+        this.body = body;
+    }
+
+    public byte[] getBody() {
+        return body;
+    }
+
+    public Header[] getAllHeaders() {
+        return responseHeaders;
+    }
+
+    public void setResponseHeaders(Header[] responseHeaders) {
+        this.responseHeaders = responseHeaders;
+    }
+
+    public Header getFirstHeader(String name) {
+        for (Header h : responseHeaders) {
+            if (h.getName().equals(name))
+                return h;
+        }
+
+        return null;
+    }
+
+    public Header[] getHeaders(String name) {
+
+        ArrayList<Header> headers = new ArrayList<Header>();
+
+        for (Header h : this.responseHeaders) {
+            if (h.getName().equals(name))
+                headers.add(h);
+        }
+
+        Header[] headerArray = new Header[headers.size()];
+
+        headers.toArray(headerArray);
+
+        return headerArray;
+    }
+
+    /**
+     *
+     * @return Response Date header value
+     */
+    protected Date getDateValue() {
+        Header dateHdr = getFirstHeader(HeaderConstants.DATE);
+        if (dateHdr == null)
+            return null;
+        try {
+            return DateUtils.parseDate(dateHdr.getValue());
+        } catch (DateParseException dpe) {
+            // ignore malformed date
+        }
+        return null;
+    }
+
+    protected long getContentLengthValue() {
+        Header cl = getFirstHeader(HeaderConstants.CONTENT_LENGTH);
+        if (cl == null)
+            return -1;
+
+        try {
+            return Long.parseLong(cl.getValue());
+        } catch (NumberFormatException ex) {
+            return -1;
+        }
+    }
+
+    /**
+     * This matters for deciding whether the cache entry is valid to serve as a
+     * response. If these values do not match, we might have a partial response
+     *
+     * @return boolean indicating whether actual length matches Content-Length
+     */
+    protected boolean contentLengthHeaderMatchesActualLength() {
+        return getContentLengthValue() == body.length;
+    }
+
+    /**
+     *
+     * @return Apparent age of the response
+     */
+    protected long getApparentAgeSecs() {
+        Date dateValue = getDateValue();
+        if (dateValue == null)
+            return MAX_AGE;
+        long diff = responseDate.getTime() - dateValue.getTime();
+        if (diff < 0L)
+            return 0;
+        return (diff / 1000);
+    }
+
+    /**
+     *
+     * @return Response Age header value
+     */
+    protected long getAgeValue() {
+        long ageValue = 0;
+        for (Header hdr : getHeaders(HeaderConstants.AGE)) {
+            long hdrAge;
+            try {
+                hdrAge = Long.parseLong(hdr.getValue());
+                if (hdrAge < 0) {
+                    hdrAge = MAX_AGE;
+                }
+            } catch (NumberFormatException nfe) {
+                hdrAge = MAX_AGE;
+            }
+            ageValue = (hdrAge > ageValue) ? hdrAge : ageValue;
+        }
+        return ageValue;
+    }
+
+    protected long getCorrectedReceivedAgeSecs() {
+        long apparentAge = getApparentAgeSecs();
+        long ageValue = getAgeValue();
+        return (apparentAge > ageValue) ? apparentAge : ageValue;
+    }
+
+    /**
+     *
+     * @return Delay between request and response
+     */
+    protected long getResponseDelaySecs() {
+        long diff = responseDate.getTime() - requestDate.getTime();
+        return (diff / 1000L);
+    }
+
+    protected long getCorrectedInitialAgeSecs() {
+        return getCorrectedReceivedAgeSecs() + getResponseDelaySecs();
+    }
+
+    protected Date getCurrentDate() {
+        return new Date();
+    }
+
+    protected long getResidentTimeSecs() {
+        long diff = getCurrentDate().getTime() - responseDate.getTime();
+        return (diff / 1000L);
+    }
+
+    public long getCurrentAgeSecs() {
+        return getCorrectedInitialAgeSecs() + getResidentTimeSecs();
+    }
+
+    protected long getMaxAge() {
+        long maxage = -1;
+        for (Header hdr : getHeaders(HeaderConstants.CACHE_CONTROL)) {
+            for (HeaderElement elt : hdr.getElements()) {
+                if (HeaderConstants.CACHE_CONTROL_MAX_AGE.equals(elt.getName())
+                        || "s-maxage".equals(elt.getName())) {
+                    try {
+                        long currMaxAge = Long.parseLong(elt.getValue());
+                        if (maxage == -1 || currMaxAge < maxage) {
+                            maxage = currMaxAge;
+                        }
+                    } catch (NumberFormatException nfe) {
+                        // be conservative if can't parse
+                        maxage = 0;
+                    }
+                }
+            }
+        }
+        return maxage;
+    }
+
+    protected Date getExpirationDate() {
+        Header expiresHeader = getFirstHeader(HeaderConstants.EXPIRES);
+        if (expiresHeader == null)
+            return null;
+        try {
+            return DateUtils.parseDate(expiresHeader.getValue());
+        } catch (DateParseException dpe) {
+            // malformed expires header
+        }
+        return null;
+    }
+
+    public long getFreshnessLifetimeSecs() {
+        long maxage = getMaxAge();
+        if (maxage > -1)
+            return maxage;
+
+        Date dateValue = getDateValue();
+        if (dateValue == null)
+            return 0L;
+
+        Date expiry = getExpirationDate();
+        if (expiry == null)
+            return 0;
+        long diff = expiry.getTime() - dateValue.getTime();
+        return (diff / 1000);
+    }
+
+    public boolean isResponseFresh() {
+        return (getCurrentAgeSecs() < getFreshnessLifetimeSecs());
+    }
+
+    /**
+     *
+     * @return boolean indicating whether ETag or Last-Modified responseHeaders
+     *         are present
+     */
+    public boolean isRevalidatable() {
+        return getFirstHeader(HeaderConstants.ETAG) != null
+                || getFirstHeader(HeaderConstants.LAST_MODIFIED) != null;
+
+    }
+
+    public boolean modifiedSince(HttpRequest request) {
+        Header unmodHeader = request.getFirstHeader(HeaderConstants.IF_UNMODIFIED_SINCE);
+
+        if (unmodHeader == null) {
+            return false;
+        }
+
+        try {
+            Date unmodifiedSinceDate = DateUtils.parseDate(unmodHeader.getValue());
+            Date lastModifiedDate = DateUtils.parseDate(getFirstHeader(
+                    HeaderConstants.LAST_MODIFIED).getValue());
+
+            if (unmodifiedSinceDate.before(lastModifiedDate)) {
+                return true;
+            }
+        } catch (DateParseException e) {
+            return false;
+        }
+
+        return false;
+    }
+
+    /**
+     *
+     * @return boolean indicating whether any Vary responseHeaders are present
+     */
+    public boolean hasVariants() {
+        return (getFirstHeader(HeaderConstants.VARY) != null);
+    }
+
+    private void writeObject(ObjectOutputStream out) throws IOException {
+
+        // write CacheEntry
+        out.defaultWriteObject();
+
+        // write (non-serializable) responseHeaders
+        if (null == responseHeaders || responseHeaders.length < 1)
+            return;
+        String[][] sheaders = new String[responseHeaders.length][2];
+        for (int i = 0; i < responseHeaders.length; i++) {
+            sheaders[i][0] = responseHeaders[i].getName();
+            sheaders[i][1] = responseHeaders[i].getValue();
+        }
+        out.writeObject(sheaders);
+
+    }
+
+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+
+        // read CacheEntry
+        in.defaultReadObject();
+
+        // read (non-serializable) responseHeaders
+        String[][] sheaders = (String[][]) in.readObject();
+        if (null == sheaders || sheaders.length < 1)
+            return;
+        BasicHeader[] headers = new BasicHeader[sheaders.length];
+        for (int i = 0; i < sheaders.length; i++) {
+            String[] sheader = sheaders[i];
+            headers[i] = new BasicHeader(sheader[0], sheader[1]);
+        }
+        this.responseHeaders = headers;
+
+    }
+
+    public void addVariantURI(String URI) {
+        this.variantURIs.add(URI);
+    }
+
+    public Set<String> getVariantURIs() {
+        return Collections.unmodifiableSet(this.variantURIs);
+    }
+}

Added: httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/CacheEntryGenerator.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/CacheEntryGenerator.java?rev=939814&view=auto
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/CacheEntryGenerator.java (added)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/CacheEntryGenerator.java Fri Apr 30 21:00:08 2010
@@ -0,0 +1,45 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.http.client.cache.impl;
+
+import java.io.IOException;
+import java.util.Date;
+
+import org.apache.http.HttpResponse;
+
+/**
+ * @since 4.1
+ */
+public class CacheEntryGenerator {
+
+    public CacheEntry generateEntry(Date requestDate, Date responseDate, HttpResponse response,
+            byte[] responseBytes) throws IOException {
+
+        return new CacheEntry(requestDate, responseDate, response, responseBytes);
+
+    }
+}

Added: httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/CacheEntryUpdater.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/CacheEntryUpdater.java?rev=939814&view=auto
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/CacheEntryUpdater.java (added)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/CacheEntryUpdater.java Fri Apr 30 21:00:08 2010
@@ -0,0 +1,130 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.http.client.cache.impl;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.apache.http.Header;
+import org.apache.http.HttpResponse;
+import org.apache.http.impl.cookie.DateParseException;
+import org.apache.http.impl.cookie.DateUtils;
+
+/**
+ * @since 4.1
+ */
+public class CacheEntryUpdater {
+
+    public void updateCacheEntry(CacheEntry entry, Date requestDate, Date responseDate,
+            HttpResponse response) {
+        entry.setRequestDate(requestDate);
+        entry.setResponseDate(responseDate);
+        mergeHeaders(entry, response);
+    }
+
+    protected void mergeHeaders(CacheEntry entry, HttpResponse response) {
+        List<Header> cacheEntryHeaderList = new ArrayList<Header>(Arrays.asList(entry
+                .getAllHeaders()));
+
+        if (entryAndResponseHaveDateHeader(entry, response)
+                && entryDateHeaderNewerThenResponse(entry, response)) {
+            // Don't merge Headers, keep the entries headers as they are newer.
+            removeCacheEntry1xxWarnings(cacheEntryHeaderList, entry);
+
+            return;
+        }
+
+        removeCacheHeadersThatMatchResponse(cacheEntryHeaderList, response);
+
+        cacheEntryHeaderList.addAll(Arrays.asList(response.getAllHeaders()));
+        removeCacheEntry1xxWarnings(cacheEntryHeaderList, entry);
+
+        entry.setResponseHeaders(cacheEntryHeaderList.toArray(new Header[cacheEntryHeaderList
+                .size()]));
+    }
+
+    private void removeCacheHeadersThatMatchResponse(List<Header> cacheEntryHeaderList,
+            HttpResponse response) {
+        for (Header responseHeader : response.getAllHeaders()) {
+            ListIterator<Header> cacheEntryHeaderListIter = cacheEntryHeaderList.listIterator();
+
+            while (cacheEntryHeaderListIter.hasNext()) {
+                String cacheEntryHeaderName = cacheEntryHeaderListIter.next().getName();
+
+                if (cacheEntryHeaderName.equals(responseHeader.getName())) {
+                    cacheEntryHeaderListIter.remove();
+                }
+            }
+        }
+    }
+
+    private void removeCacheEntry1xxWarnings(List<Header> cacheEntryHeaderList, CacheEntry entry) {
+        ListIterator<Header> cacheEntryHeaderListIter = cacheEntryHeaderList.listIterator();
+
+        while (cacheEntryHeaderListIter.hasNext()) {
+            String cacheEntryHeaderName = cacheEntryHeaderListIter.next().getName();
+
+            if (HeaderConstants.WARNING.equals(cacheEntryHeaderName)) {
+                for (Header cacheEntryWarning : entry.getHeaders(HeaderConstants.WARNING)) {
+                    if (cacheEntryWarning.getValue().startsWith("1")) {
+                        cacheEntryHeaderListIter.remove();
+                    }
+                }
+            }
+        }
+    }
+
+    private boolean entryDateHeaderNewerThenResponse(CacheEntry entry, HttpResponse response) {
+        try {
+            Date entryDate = DateUtils.parseDate(entry.getFirstHeader(HeaderConstants.DATE)
+                    .getValue());
+            Date responseDate = DateUtils.parseDate(response.getFirstHeader(HeaderConstants.DATE)
+                    .getValue());
+
+            if (!entryDate.after(responseDate)) {
+                return false;
+            }
+        } catch (DateParseException e) {
+            return false;
+        }
+
+        return true;
+    }
+
+    private boolean entryAndResponseHaveDateHeader(CacheEntry entry, HttpResponse response) {
+        if (entry.getFirstHeader(HeaderConstants.DATE) != null
+                && response.getFirstHeader(HeaderConstants.DATE) != null) {
+            return true;
+        }
+
+        return false;
+    }
+
+}

Added: httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/CacheInvalidator.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/CacheInvalidator.java?rev=939814&view=auto
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/CacheInvalidator.java (added)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/CacheInvalidator.java Fri Apr 30 21:00:08 2010
@@ -0,0 +1,125 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.http.client.cache.impl;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.http.Header;
+import org.apache.http.HeaderElement;
+import org.apache.http.HttpHost;
+import org.apache.http.HttpRequest;
+import org.apache.http.client.cache.HttpCacheOperationException;
+import org.apache.http.client.cache.HttpCache;
+
+/**
+ * Given a particular HttpRequest, flush any cache entries that this request
+ * would invalidate.
+ *
+ * @since 4.1
+ */
+public class CacheInvalidator {
+
+    private HttpCache<CacheEntry> cache;
+    private URIExtractor uriExtractor;
+
+    private static final Log LOG = LogFactory.getLog(CacheInvalidator.class);
+
+    public CacheInvalidator(URIExtractor uriExtractor, HttpCache<CacheEntry> cache) {
+        this.uriExtractor = uriExtractor;
+        this.cache = cache;
+    }
+
+    public void flushInvalidatedCacheEntries(HttpHost host, HttpRequest req) {
+        LOG.debug("CacheInvalidator: flushInvalidatedCacheEntries, BEGIN");
+
+        if (requestShouldNotBeCached(req)) {
+            LOG
+                    .debug("CacheInvalidator: flushInvalidatedCacheEntries, Request should not be cached");
+
+            try {
+                String theUri = uriExtractor.getURI(host, req);
+
+                CacheEntry parent = cache.getEntry(theUri);
+
+                LOG.debug("CacheInvalidator: flushInvalidatedCacheEntries: " + parent);
+
+                if (parent != null) {
+                    for (String variantURI : parent.getVariantURIs()) {
+                        cache.removeEntry(variantURI);
+                    }
+                    cache.removeEntry(theUri);
+                }
+            } catch (HttpCacheOperationException coe) {
+                // TODO: track failed state
+            }
+        }
+    }
+
+    protected boolean requestShouldNotBeCached(HttpRequest req) {
+        String method = req.getRequestLine().getMethod();
+        return notGetOrHeadRequest(method) || containsCacheControlHeader(req)
+                || containsPragmaHeader(req);
+    }
+
+    private boolean notGetOrHeadRequest(String method) {
+        return !(HeaderConstants.GET_METHOD.equals(method) || HeaderConstants.HEAD_METHOD
+                .equals(method));
+    }
+
+    private boolean containsPragmaHeader(HttpRequest req) {
+        return req.getFirstHeader(HeaderConstants.PRAGMA) != null;
+    }
+
+    private boolean containsCacheControlHeader(HttpRequest request) {
+        Header[] cacheControlHeaders = request.getHeaders(HeaderConstants.CACHE_CONTROL);
+
+        if (cacheControlHeaders == null) {
+            return false;
+        }
+
+        for (Header cacheControl : cacheControlHeaders) {
+            HeaderElement[] cacheControlElements = cacheControl.getElements();
+            if (cacheControlElements == null) {
+                return false;
+            }
+
+            for (HeaderElement cacheControlElement : cacheControlElements) {
+                if (HeaderConstants.CACHE_CONTROL_NO_CACHE.equalsIgnoreCase(cacheControlElement
+                        .getName())) {
+                    return true;
+                }
+
+                if (HeaderConstants.CACHE_CONTROL_NO_STORE.equalsIgnoreCase(cacheControlElement
+                        .getName())) {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+}
\ No newline at end of file

Added: httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/CacheableRequestPolicy.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/CacheableRequestPolicy.java?rev=939814&view=auto
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/CacheableRequestPolicy.java (added)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/impl/CacheableRequestPolicy.java Fri Apr 30 21:00:08 2010
@@ -0,0 +1,92 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.http.client.cache.impl;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.http.Header;
+import org.apache.http.HeaderElement;
+import org.apache.http.HttpRequest;
+import org.apache.http.ProtocolVersion;
+
+/**
+ * Determines if an HttpRequest is allowed to be served from the cache.
+ *
+ * @since 4.1
+ */
+public class CacheableRequestPolicy {
+
+    private static final Log LOG = LogFactory.getLog(CacheableRequestPolicy.class);
+
+    /**
+     * Determines if an HttpRequest can be served from the cache.
+     *
+     * @param request
+     *            an HttpRequest
+     * @return boolean Is it possible to serve this request from cache
+     */
+    public boolean isServableFromCache(HttpRequest request) {
+        String method = request.getRequestLine().getMethod();
+
+        ProtocolVersion pv = request.getRequestLine().getProtocolVersion();
+        if (CachingHttpClient.HTTP_1_1.compareToVersion(pv) != 0) {
+            LOG.debug("CacheableRequestPolicy: Request WAS NOT serveable from Cache.");
+            return false;
+        }
+
+        if (!method.equals(HeaderConstants.GET_METHOD)) {
+            LOG.debug("CacheableRequestPolicy: Request WAS NOT serveable from Cache.");
+            return false;
+        }
+
+        if (request.getHeaders(HeaderConstants.PRAGMA).length > 0) {
+            LOG.debug("CacheableRequestPolicy: Request WAS NOT serveable from Cache.");
+            return false;
+        }
+
+        Header[] cacheControlHeaders = request.getHeaders(HeaderConstants.CACHE_CONTROL);
+        for (Header cacheControl : cacheControlHeaders) {
+            for (HeaderElement cacheControlElement : cacheControl.getElements()) {
+                if (HeaderConstants.CACHE_CONTROL_NO_STORE.equalsIgnoreCase(cacheControlElement
+                        .getName())) {
+                    LOG.debug("CacheableRequestPolicy: Request WAS NOT serveable from Cache.");
+                    return false;
+                }
+
+                if (HeaderConstants.CACHE_CONTROL_NO_CACHE.equalsIgnoreCase(cacheControlElement
+                        .getName())) {
+                    LOG.debug("CacheableRequestPolicy: Request WAS NOT serveable from Cache.");
+                    return false;
+                }
+            }
+        }
+
+        LOG.debug("CacheableRequestPolicy: Request WAS serveable from Cache.");
+        return true;
+    }
+
+}