Keeping HttpContext per working thread results in having SSL handshake done for each HttpContext object, doesn't it?
2013/9/5 Oleg Kalnichevski <[email protected]> > On Thu, 2013-09-05 at 15:17 +0200, Mateusz P wrote: > > Ok, i think we misunderstood each other. As I wrote in my initial email I > > work on highly multithreading environment and I'm expecting all > connections > > to reuse already initiated SSL session, as they share the same url and > > client-side certificate. What you proposed, if I understood you right, is > > to keep SSL session per single working thread. > > That is not what I proposed. > > Oleg > > > My requirement was met in the old commons-http library as its connection > > discriminator was based on host and port exclusively. I'd like to keep > this > > behavior with using the new API > > Regards, > > Mateusz > > > > > > > > 2013/9/5 Oleg Kalnichevski <[email protected]> > > > > > On Thu, 2013-09-05 at 14:43 +0200, Mateusz P wrote: > > > > Oleg, > > > > While reusing http context I encountered on thread-safety issue > though. > > > > A *HttpRequest *is processed by *DefaultRequestDirector *which, among > > > > others, sets up currently used connection on the context object (a > line > > > > from v4.2.5): > > > > > > > > *515: context.setAttribute(ExecutionContext.HTTP_CONNECTION, > > > managedConn);* > > > > > > > > This value is extracted later on by *DefaultUserTokenHandler* and > used to > > > > retrieve user principal from SSL session associated with the > connection. > > > > The multithreaded case lead to situation when the session is replaced > > > > between storing and retrieving, which, causes > > > > *DefaultUserTokenHandler*cannot find the user principal. > > > > > > > > Regards, > > > > Mateusz > > > > > > > > > > I am sorry but I fail to see a threading issue here or i do not quite > > > understand what 'when the session is replaced between storing and > > > retrieving' actually means. Neither HttpContext nor HttpConnection > > > objects are thread safe and therefore may not be shared concurrently by > > > multiple threads. > > > > > > Oleg > > > > > > > > > > > > > > > 2013/9/5 Oleg Kalnichevski <[email protected]> > > > > > > > > > On Thu, 2013-09-05 at 12:55 +0200, Mateusz P wrote: > > > > > > Oleg, > > > > > > What in case sacrificing performance is not possible? > > > > > > The system I work on is a ESB gateway with high volume traffic > and > > > > > > processing requests one by one is not an option at all. > > > > > > However, all requests go to the same service and use exactly the > same > > > > > > client-side certificate in mutual SSL handshake, so they could > reuse > > > the > > > > > > connections. > > > > > > The problem would be easier to solve if there would be separation > > > between > > > > > > client context (holding all information specific for all > connections > > > like > > > > > > security context, cookie store etc) and execution context > (holding > > > > > > information specific for a particular connection). > > > > > > My temporary solution is to save the first request's context and > I > > > create > > > > > > my own BasicContext for every subsequent request and provide > > > USER_TOKEN > > > > > to > > > > > > it from the initially saved http context. > > > > > > If separation is not an option, I would appreciate utils class to > > > > > > extract/store client/execution context's attributes in one call. > > > Having > > > > > > that I could improve my solution > > > > > > Please let me know what are your thoughts on that > > > > > > Regards, > > > > > > Mateusz > > > > > > > > > > > > > > > > Mateusz > > > > > > > > > > There is absolutely nothing that prevents you from using the same > > > > > HttpContext per worker thread. Those contexts could share the same > > > > > cookie store, credentials provider or any other thread safe object. > > > > > > > > > > If the same connection pool is not used anywhere else you might as > well > > > > > disable connection state tracking. > > > > > > > > > > Oleg > > > > > > > > > > > > > > > > > On Mon, 2013-08-12 at 12:54 -0700, Erik Pilz wrote: > > > > > > > > > > > > > > Hi Oleg, > > > > > > > > > > > > > > > > Thanks for the clear and thoughtful reply explaining the > design. > > > For > > > > > my > > > > > > > own > > > > > > > > edification I was hoping you could elaborate on the scenario > > > where > > > > > > > another > > > > > > > > consumer with a different security context would introduce a > > > risk or > > > > > > > > problem. Are you referring to clients using a SSLContext > other > > > than > > > > > the > > > > > > > > system default? > > > > > > > > > > > > > > > > Thanks, > > > > > > > > Erik > > > > > > > > > > > > > > > > > > > > > > Hi Erik > > > > > > > > > > > > > > Consider the following scenario. Multiple threads consume the > same > > > > > > > service (the same route) but using a different SSLContext with > the > > > > > > > client auth set to required. The service handles requests > > > differently > > > > > > > based on the security principal of the client certificate (user > > > role). > > > > > > > You would not want HttpClient to carelessly hand out a > persistent > > > > > > > connection to that service to the very first consumer that > happens > > > to > > > > > > > request it, would you? > > > > > > > > > > > > > > It is a fairly uncommon scenario, but when it comes to > security, > > > one > > > > > > > better be safe than sorry. Security considerations override > those > > > of > > > > > > > performance. > > > > > > > > > > > > > > Hope this helps > > > > > > > > > > > > > > Oleg > > > > > > > > > > > > > > > > > > > > > > > On Sun, Aug 11, 2013 at 3:34 AM, Oleg Kalnichevski < > > > [email protected] > > > > > > > > > > > > > wrote: > > > > > > > > > > > > > > > > > On Fri, 2013-08-09 at 15:16 -0700, Erik Pilz wrote: > > > > > > > > > > We're migrating an old application from Java's > > > > > HttpsUrlConnection to > > > > > > > > > > HttpClient. After running a performance test we found a > high > > > cost > > > > > > > around > > > > > > > > > > connection acquisition. A bit of debugging later led me > to > > > find > > > > > that > > > > > > > > > we're > > > > > > > > > > not getting the full benefit of pooled connections. What > I > > > > > eventually > > > > > > > > > found > > > > > > > > > > is that I have to create a HttpClientContext and > populate the > > > > > > > userToken > > > > > > > > > > with some object and use HttpClient#execute(method, > context). > > > > > This > > > > > > > wasn't > > > > > > > > > > obvious to me; is this intentional or did I just find a > > > > > workaround > > > > > > > to a > > > > > > > > > bug? > > > > > > > > > > > > > > > > > > ... > > > > > > > > > > > > > > > > > > > Calling HttpClient#execute(method) will create a context > > > whose > > > > > > > userToken > > > > > > > > > is > > > > > > > > > > null. To work around the behavior it's instead necessary > to > > > > > create an > > > > > > > > > > HttpClientContext and populate it with a userToken of > your > > > own > > > > > (it > > > > > > > can be > > > > > > > > > > any object); this will then be used as the state in the > > > available > > > > > > > > > > connections instead of the principal from the > SSLSession; you > > > > > then > > > > > > > use > > > > > > > > > > HttpClient#execute(method, context) in place of > > > > > > > > > HttpClient#execute(method). > > > > > > > > > > > > > > > > > > > > Thanks, > > > > > > > > > > Erik > > > > > > > > > > > > > > > > > > Hi Erik > > > > > > > > > > > > > > > > > > This is by design and not a defect. > > > > > > > > > > > > > > > > > > Mutually authenticated SSL connections are considered > > > state-full > > > > > and > > > > > > > > > special measures are taken to make sure they cannot be > leased > > > to a > > > > > > > > > consumer with a different security context. Their state is > > > > > represented > > > > > > > > > by a user token, which is by default the security > principal of > > > the > > > > > > > > > client certificate. > > > > > > > > > > > > > > > > > > There are two ways you could resolve the issue > > > > > > > > > > > > > > > > > > (1) Disable connection state management if your application > > > does > > > > > not > > > > > > > > > need to maintain a different security context per worker > thread > > > > > > > > > > > > > > > > > > --- > > > > > > > > > CloseableHttpClient client = HttpClients.custom() > > > > > > > > > .disableConnectionState() > > > > > > > > > .build(); > > > > > > > > > --- > > > > > > > > > > > > > > > > > > (2) Simply make related requests share the same context > > > > > (recommended). > > > > > > > > > In this case SSL security principal of the initial request > > > will be > > > > > > > added > > > > > > > > > to the execution context as a user token and propagated to > all > > > > > > > > > subsequent requests. When leasing a persistent connection > from > > > the > > > > > > > > > connection pool HttpClient will use the user token to > request a > > > > > > > > > connection with a specific state / security context. > > > > > > > > > > > > > > > > > > --- > > > > > > > > > CloseableHttpClient client = HttpClients.custom() > > > > > > > > > .build(); > > > > > > > > > HttpClientContext context = HttpClientContext.create(); > > > > > > > > > HttpGet get1 = new HttpGet("https://myhost/this"); > > > > > > > > > CloseableHttpResponse response1 = client.execute(get1, > > > context); > > > > > > > > > try { > > > > > > > > > > > > > > > > > > } finally { > > > > > > > > > response1.close(); > > > > > > > > > } > > > > > > > > > HttpGet get2 = new HttpGet("https://myhost/that"); > > > > > > > > > CloseableHttpResponse response2 = client.execute(get2, > > > context); > > > > > > > > > try { > > > > > > > > > > > > > > > > > > } finally { > > > > > > > > > response1.close(); > > > > > > > > > } > > > > > > > > > --- > > > > > > > > > > > > > > > > > > Oleg > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > --------------------------------------------------------------------- > > > > > > > > > To unsubscribe, e-mail: > > > [email protected] > > > > > > > > > For additional commands, e-mail: > > > > > [email protected] > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > --------------------------------------------------------------------- > > > > > To unsubscribe, e-mail: [email protected] > > > > > For additional commands, e-mail: > [email protected] > > > > > > > > > > > > > > > > > > > > > > --------------------------------------------------------------------- > > > To unsubscribe, e-mail: [email protected] > > > For additional commands, e-mail: [email protected] > > > > > > > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [email protected] > For additional commands, e-mail: [email protected] > >
