On Thu, 2012-05-31 at 11:28 +0200, Jose Escobar wrote: > I have investigated the custom socket factory but I don't find the way > to use it with a dynamically expandable list of certificates (I can > get new certificates for specific Urls at runtime). Nearest > aproximation I found was Embby's answer at > http://stackoverflow.com/questions/2642777/trusting-all-certificates-using-httpclient-over-https > but doesn't fit to my requirements at all. > > My solution, change the context for each request if needed, fits my > requirements and apparently worked until you say it could fail. I'm > going to investigate more in a custom socket factory solution, however > could you suggest me what should I override on a custom socket factory > that let me read the url of a socket request and change trust > certificates (getting from a database for example) based on the > hostname of the target server. > > > Thank you very much! > > Jose E. >
Jose You solution is perfectly valid for your particular application context. What i was trying to say was that this approach might not be applicable to all cases and should not be used per default. Hope this makes my position somewhat clearer. Oleg > 2012/5/30 Oleg Kalnichevski <[email protected]>: > > On Wed, 2012-05-30 at 14:02 +0200, Jose Escobar wrote: > >> Hi, > >> > >> Finally I found a solution. > >> I create a new SchemeRegistry on each request thread that need > >> specific trust and key material and I add it as a SCHEME_REGISTRY > >> attribute to a Context variable(each thread maintains its own > >> dedicated instance of HttpContext). Then I use the singleton > >> httpClient and that new context to execute the request. Using this I > >> can use a custom SchemeRegistry for each request with a singleton > >> httpclient bean. > >> > >> BUT I found that SCHEME_REGISTRY context attribute is not working > >> properly in httpclient execute method (httpClient.execute(httpPost, > >> context);) I dig into httpclient code to discover that this attribute > >> is not readed. I isolate the problem to a single class, > >> org.apache.http.impl.conn.DefaultClientConnectionOperator. The method > >> openConnection gets default schemeRegistry instead of look first at > >> context, so I write some code to fix this and it works great now. > >> > >> BEFORE: > >> > >> public void openConnection( > >> final OperatedClientConnection conn, > >> final HttpHost target, > >> final InetAddress local, > >> final HttpContext context, > >> final HttpParams params) throws IOException { > >> if (conn == null) { > >> throw new IllegalArgumentException("Connection may not be > >> null"); > >> } > >> if (target == null) { > >> throw new IllegalArgumentException("Target host may not be > >> null"); > >> } > >> if (params == null) { > >> throw new IllegalArgumentException("Parameters may not be > >> null"); > >> } > >> if (conn.isOpen()) { > >> throw new IllegalStateException("Connection must not be open"); > >> } > >> > >> Scheme schm = schemeRegistry.getScheme(target.getSchemeName()); > >> SchemeSocketFactory sf = schm.getSchemeSocketFactory(); > >> . > >> . > >> . > >> > >> AFTER: > >> > >> public void openConnection( > >> final OperatedClientConnection conn, > >> final HttpHost target, > >> final InetAddress local, > >> final HttpContext context, > >> final HttpParams params) throws IOException { > >> if (conn == null) { > >> throw new IllegalArgumentException("Connection may not be > >> null"); > >> } > >> if (target == null) { > >> throw new IllegalArgumentException("Target host may not be > >> null"); > >> } > >> if (params == null) { > >> throw new IllegalArgumentException("Parameters may not be > >> null"); > >> } > >> if (conn.isOpen()) { > >> throw new IllegalStateException("Connection must not be open"); > >> } > >> //Changes here! > >> Scheme schm; > >> if ((context != null) && > >> (context.getAttribute(ClientContext.SCHEME_REGISTRY) != null)) { > >> schm = > >> ((SchemeRegistry)context.getAttribute(ClientContext.SCHEME_REGISTRY)).getScheme(target.getSchemeName()); > >> } > >> else { > >> schm = schemeRegistry.getScheme(target.getSchemeName()); > >> } > >> > >> SchemeSocketFactory sf = schm.getSchemeSocketFactory(); > >> . > >> . > >> . > >> > >> > >> I can send a patch if you find it correct, for me it works. > >> > > > > You see, the problem is that if sockets can be created by arbitrary > > socket factories HTTP connections bound to those sockets can have > > context specific state the connection manager is not aware of. So, the > > connection manager can end up leasing those connections to another > > execution thread with a completely different security / user context. > > > > Why did you choose to not create a custom socket factory? > > > > 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]
