hc-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Oleg Kalnichevski <ol...@apache.org>
Subject Re: [HttpCore] mutability and immutability no more?
Date Mon, 13 Feb 2006 09:36:45 GMT
On Sun, 2006-02-12 at 19:15 +0100, Roland Weber wrote: 
> Hi Oleg, hi all,
> I'm not quite happy with the way http-core currently handles
> mutable vs. immutable messages, in particular requests. There
> is an instanceof check in HttpRequestExecutor: if a request
> is an instance of HttpMutableRequest, it is preprocessed. If
> it is not an instance of that interface, preprocessing is
> skipped. This has some questionable implications:
> - the default implementations we have (HttpGet, HttpPost)
>   implement the mutable interface and can not be protected
>   from being modified (out of the box)
> - if an application implements the non-mutable interface,
>   the skipping of preprocessing will most likely result in
>   an invalid request being sent. In other words:
> - although the signature of HttpRequestExecutor.execute
>   declares to expect an immutable request, it actually
>   requires a mutable request to function properly
> - the design is not "fair", meaning: we implicitly expect
>   applications to respect immutability if we declare a
>   return value with an immutable interface, but our code
>   does not show the same respect towards the application
> Yes, the last three points are more or less the same.
> That just shows you how many facets my unhappiness has :-)
> One other point which seems unrelated at first sight is
> the distinction between auto-generated headers and headers
> provided by the application. In HttpClient < 4.0, this is
> used to "undo" modifications to a request before retrying,
> I think in the method director.
> This design restricts our request interceptors to adding
> headers. Removing a header, or changing a header value,
> are operations that can not be undone. Even if we might
> not provide interceptors that modify header values, the
> mechanism is meant for use by application developers too.
> Not allowing modifications or removal of headers is a
> significant restriction. Some headers for which modifications
> can be useful are Cookie, Connection, Content-Encoding.
> An alternative way to address mutability and immutability
> is through the use of wrappers. I have seen this technique
> applied in similar scenarios. The Servlet API added wrappers
> for requests and responses with version 2.3:
> http://java.sun.com/j2ee/1.4/docs/api/javax/servlet/http/package-summary.html
> The idea is as follows: instead of an instanceof check to
> decide whether request preprocessing should be performed,
> a mutable wrapper is created for the request. Preprocessing
> is *always* performed, modifications apply only to the
> wrapper. The auto-generated flag for Headers is pointless,
> modifications are undone by forgetting about the wrapper.
> Wrappers that implement only the non-mutable interfaces
> can be used to protect against unintentional modifications
> of objects.
> This change is based on a different interpretation of
> "immutable". To me, immutable doesn't mean that a request
> is sent without being processed by the interceptors.
> It means that the object in memory is not modified.
> If you feel like you've got a deja vu now, here's why:
> http://mail-archives.apache.org/mod_mbox/jakarta-httpclient-dev/200503.mbox/%3cOFF61E99BB.5D1DEACB-ONC1256FD3.003C83FB-C1256FD3.003EF2AF@de.ibm.com%3e
> Based on the result of this discussion, I will try to come
> up with a patch next weekend - or not.
> There would be some followup issues because the distinction
> between entity enclosing and header-only requests is currently
> based on another instanceof check. This can be addressed by
> implementing plenty of different wrapper classes, or by
> removing the instanceof check in favor of a flag that can be
> queried. (We don't have different response classes either.)
> But that is a secondary issue to the big question:
> to wrap or not to wrap?


Frankly, I do not think this would be a better solution. There are
situations where one does want the original request object to mutate in
order to be able to examine its post-execution state. If we wrapped the
original request object all mutations to it would be lost along with the

I have a more radical change to suggest. I am beginning to suspect the
whole concept of mutable/immutable HTTP messages while being
conceptually nice does not seem to bring any tangible benefits in
practical terms.   

In the very beginning I still thought we might want to stick some of the
protocol logic into HttpRequest/HttpResponse class hierarchy (for
instance 'Host' header), which would require some complex methods
mutating the state of the request objects. This proved unnecessary. Now
we have all HTTP protocol logic neatly encapsulated in the
request/response interceptors and the control logic encapsulated in
various HTTP processors. HTTP messages have been reduced to being pure
value objects, which is great. Probably we ought to start thinking of
HttpRequest/HttpResponse classes as representing value objects, which
are always mutable. 

I suggest we just do away with HttpMutable* interfaces 


> I'm signing off now, it's been a long day. Looking forward
> to read your comments tomorrow.
> cheers,
>   Roland
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: httpclient-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: httpclient-dev-help@jakarta.apache.org

To unsubscribe, e-mail: httpclient-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: httpclient-dev-help@jakarta.apache.org

View raw message