cxf-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Oleg Kalnichevski <>
Subject Re: Async http client experiments....
Date Wed, 05 Sep 2012 13:26:06 GMT
On Tue, 2012-09-04 at 15:20 -0400, Daniel Kulp wrote:
> On Aug 6, 2012, at 10:43 AM, Oleg Kalnichevski <> wrote:
> >>>> CXF allows these to be configured on a per-client (and sometimes even
> >>>> per- request) basis.    It looks like HC seems to have these on the
> >>>> connection factory.
> >>> 
> >>> It does not have to be this way. Connections can start off as plain and
> >>> later get upgraded to TLS/SSL by the protocol handling code. One would
> >>> have to tweak the default protocol handler a bit, though, probably by
> >>> overriding the HttpAsyncRequestExecutor#requestReady method [2].
> >> 
> >> Ah.  OK.   I'll take a look there.   I was looking in the various connection

> >> factories and pools.   Haven't looked there yet.   Lots of stuff going on. 

> >> :-)
> >> 
> > 
> > I also added a CXF specific connection manager implementation in order
> > to enable SSL customization based on request configuration. However,
> > before I proceed I would like to understand the requirements a little
> > better. Can I assume that once an SSL connection has been fully set up
> > using request level config parameters and can be pooled and safely
> > reused for subsequent requests to the same service (even by different
> > users) or requests may contain different / incompatible SSL
> > configuration for the same service?   
> They may contain different configurations.  Particular different client certs if using
client certs as the authentication mechanism. 
> I found the "state" object to pass into the connection factory and plan on implementing
a new state object that will attempt to handle that by comparing the various values on the
HTTPConduit settings.    However, I *DID* run into a couple problems that, while I was able
to work around them with some hacks, they likely should be fixed in the HTTP stuff.  In particular:
> 1) The "state" object that is passed into the factory is never saved anywhere.   IMO,
if a new connection is created based on the state, it might be good to record that state (or
at least make that an option) so the state stuff actually works.   I got around this by subclassing
the BasicNIOConnPool to override the BasicNIOConnPool.createEntry method to add a state object
to the entry.   A bit involved.

Let me try to explain the rationale behind the design. 

HC connection pools distinguish between route info and connection state.
Routes are immutable and are well known in advance. A route in its basic
form is a scheme/host/port combo. At connection creation time only the
route matters as all HTTP connections start out their life cycle as
state-less per HTTP specification. In real life settings, however, HTTP
connections may acquire certain state during their life-cycle, for
instance, by serving a resource protected with a connection based auth
scheme such as NTLM. So, the object that represents a state of a
connection may need to be associated with the connection after it has
already been created. SSL is similar. An HTTP connection can be created
as plain and later get upgraded to TLS/SSL. If the target server
requires the client to authenticate itself with a certificate, the
connection becomes state-full after successful authentication only.   

Once a connection becomes state-full it can only be leased if requested
with the same combination of route info and state. I believe this is the
reason why you are getting a new SSL connection for each new HTTPS
request. I guess the state object used in the lease request is not equal
to that associated with the pool entry.

If in your case SSL context details are effectively a given, you should
make then a part of the route info instead of the state. HC connection
pools are designed to be able to use any arbitrary immutable class as a
route info.   

> 2) Lots of issues trying to associate the request with the connection at connection creation
time.   I needed information from the request in order to setup the SSL stuff.  However, I
had a LOT of issues trying to accomplish that.   The only thing the ConnectionFactory gets
it the IOSession.  All that has in it is the HttpHost.  The HttpHost is final.   The connect
occurs on a different thread so thread locals won't work.   Also note that all the fields
in SSLIOSession are final and private.  Thus, I also couldn't find a way to delay the SSL
setup stuff till later.  Thus, I had to get the request/connection stuff associated up front.
 I ended up using a IdentityHashMap to associate the HttpHost with the request stuff, but
it seemed very hacky.
> Not really sure what the right solution would be.   My initial thought was to make HttpHost
non-final so that I could subclass it with an CXFHttpHost or SSLHttpHost or something that
would contain extra methods that I could call.   Alternatively, add a "properties" map to
HttpHost or similar that I could store additional stuff.   Another option would be to have
the IOSession passed to the factory also contain the "state" (if specified)  as a property
that could be queried.  

Just ditch HttpHost. You obviously need a richer class to represent
connection routes. HttpClient has HttpRoute class for that matter. You
probably should be using a custom class that also includes HTTP proxy
and SSL context bits specific to CXF.

Does this help you in any way?


View raw message