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]

Reply via email to