As we've seen, we've run into a couple of problems with some of our decorators for the DefaultHttpClient where underlying backends do non-transparent things (ranging from decompressing content bodies without updating response headers, to following redirects). I do think the decorators provide a nice way to layer the overall functionality from a codebase point of view, but I think they are brittle because they rely on unenforceable assumptions (e.g. that backend clients that get injected behave transparently).
I think the solution to this is to continue using the decorators, but hide them from most users--in other words, reimplementing the DefaultHttpClient as a stack of decorators that get enabled/disabled by configuration. In other words, a user should be able to "new DefaultHttpClient()" and get something that is capable of caching, following redirects, and handling compression (per configuration). I think this looks like: (1) generate a decorator for redirect following (2) create a new class (BasicHttpClient?) that is essentially DefaultHttpClient minus the redirect logic (3) reimplement DefaultHttpClient so that it generates and configures a stack of RedirectFollowingHttpClient, DecompressingHttpClient, CachingHttpClient, BasicHttpClient (this might mean needing to pull the httpclient-cache module into the httpclient module) (4) add warning documentation on the DecompressingHttpClient and CachingHttpClient about needing to wire them up correctly (this should probably happen first, actually) I suspect there are actually other decorators lurking in there too (authentication? cookie handling?). I think this potentially gives us a clean way to layer in functionality--implement it as a decorator and then figure out where in the stack is the right/safe way to add it. Opting into the new functionality is a matter of turning it on in the config for DefaultHttpClient, which is far simpler for users to do. Thoughts? Jon
