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/[EMAIL PROTECTED] 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? I'm signing off now, it's been a long day. Looking forward to read your comments tomorrow. cheers, Roland --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
