XML-RPC

Possibility to subclass XmlRpcSunHttpTransport for added functionality

Created: 31/Jul/06 06:22 PM   Updated: 28/Nov/08 08:53 PM
Return to search
Component/s: Source
Affects Version/s: 3.0rc1
Fix Version/s: None

Time Tracking:
Not Specified

File Attachments:
  Size
Text File Licensed for inclusion in ASF works ssl.patch 2006-08-01 05:29 AM Julio Francisco Veronelli 7 kB
Zip Archive Licensed for inclusion in ASF works sunhttp.zip 2006-08-01 05:07 PM Julio Francisco Veronelli 4 kB

Resolution Date: 27/Oct/07 08:16 PM


 Description  « Hide
Could it be possible to make the URLConnection in class org.apache.xmlrpc.client.XmlRpcSunHttpTransport protected instead of private? That is:

protected URLConnection conn;


REASON:
That way is much easier to subclass for added functionality. In particular, i'm subclassing it to set a java.net.Proxy or a java.security.KeyStore used for setting a SSL connection.

In XML-RPC 3.0a1 it was easy to do, all that was needed was to subclass method newConnection(). In 3.0RC1 that method is gone, and overwriting sendRequest(XmlRpcRequest) is not possible, since conn is private.

I tried also extending XmlRpcHttpTransport, but it is not possible, because org.apache.xmlrpc.client.XmlRpcStreamTransport.RequestWriter is protected and cannot be accessed.

Thanks in advance.

 All   Comments   Work Log   Change History   Subversion Commits      Sort Order: Ascending order - Click to sort in descending order
Julio Francisco Veronelli added a comment - 31/Jul/06 06:34 PM
I copy the method i'm trying to overwrite as an example. I think it would be a nice improvement to be able to create a customized connection by overwriting a method in XmlRpcSunHttpTransport.

  public Object sendRequest(XmlRpcRequest pRequest) throws XmlRpcException {
    XmlRpcHttpClientConfig config = (XmlRpcHttpClientConfig)pRequest.getConfig();
    URLConnection result = null;
    try {
      //TIP set trusted certificates
      if ((_sslFactory == null) && (_keystore != null)) {
        TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
        tmf.init(_keystore);
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null,tmf.getTrustManagers(),null);
        _sslFactory = sslContext.getSocketFactory();
      }
      //TIP create connection
      URL url = config.getServerURL();
      if (_proxy != null) result = url.openConnection(_proxy);
      else result = url.openConnection();
      if ((_sslFactory != null) && (result instanceof HttpsURLConnection))
        ((HttpsURLConnection)result).setSSLSocketFactory(_sslFactory);
      result.setUseCaches(false);
      result.setDoInput(true);
      result.setDoOutput(true);
    }
    catch (GeneralSecurityException ex) {
      throw new XmlRpcException("Failed to set certificate trust chain",ex);
    }
    catch (Exception ex) {
      throw new XmlRpcException("Failed to create URLConnection: " + ex.getMessage(),ex);
    }
    return super.sendRequest(pRequest);
  }

Jochen Wiedmann added a comment - 31/Jul/06 08:45 PM
I see two completely different topics here:

- The use of a proxy server is definitely of general interest and a common requirement.
   It can be easily picked up by the commons and the lite http transport as well. In
   other words, I suggest that we change this into a configurable property of the
   XmlRpcHttpClient. For example, the property might take an instance of the
   following class:

       public class HttpProxy {
           URL proxyURL;
           String user, password;
       }

  Are you ready to provide a patch for that?

- The use of an SSLSocketFactory is slightly different from

      http://ws.apache.org/xmlrpc/ssl.html

  As far as I can tell the basic difference is that you are setting the trust manager
  per connection, which is of course recommendable over a static setting. I am
  considering how this might be integrated, too. One more patch?

Julio Francisco Veronelli added a comment - 01/Aug/06 05:28 AM
I'm tackling the SSL thingy first. Attached is a patch for setting a SSLSocketFactory that will be used in https connections.

XmlRpcSunHttpTransport has been modified, as well as it's factory.

XmlRpcLiteHttpTransport did not even allow https connections, but hopefully now they are allowed whether or not a SSLSocketFactory is given (factory also modified). (Also, perhaps sendRequest() should throw an Exception if url.getProtocol() does not return http or https?)

As for XmlRpcCommonsTransport, I could not easily find how to set a SSLSocketFactory, so I skipped that one.

Note that all changes require Java 1.4 or later (I don't know what if the minimum version is).

As a sidenote, if I'm right, the tutorial in http://ws.apache.org/xmlrpc/ssl.html works only in a XmlRpcSunHttpTransport. If true, maybe it should be warned within the tutorial.

Hope any of this helps.

Julio Francisco Veronelli added a comment - 01/Aug/06 05:29 AM
The SSL patches of the comment before.

Julio Francisco Veronelli added a comment - 01/Aug/06 05:42 AM
Now, about the HTTP proxy thing, seems ok what you suggest. But I think there are a couple of problems with that:

1) The sample I gave, in which a java.net.Proxy is used requires Java 1.5 or later. Perhaps a XmlRpcSun15HttpTransport (and factory) could be used? Even if done that way, the Proxy class does not allow to set a user or password, so only the address would be given.

2) From what i saw, HttpClient provides a HostConfiguration.setProxy(String proxyHost,int proxyPort) that may be used. But, again, only the address can be set.

3) Finally, for the Lite transport, it's way beyond my skill how to talk directly to a HTTP Proxy using a socket. Sorry about that.

I think I can provide a patch for (1) and (2), but no more than that. Cheers.

Jochen Wiedmann added a comment - 01/Aug/06 05:53 AM
There's nothing wrong with using Java 1.4 (or even 1.5 features), as long as the respective code is clearly separated. Take, for example, the CharSetXmlWriter. That's one important reason for using the factory approach: The factory allows you to check, which Java version you are running. Based on the check, the proper implementation will be returned.

In other words, please be so kind to modify your patch in the following manner:

- First of all, for now forget about the lite and commons classes. Sorry, that I haven't mentioned this earlier.
  It simplifies and reduces your work and may well be deferred until we agree on the interface.
- In the XmlRpcSunHttpTransportFactory, check whether one is running 1.4 or 1.5. The check should be
  implemented by validating the existence of appropriate classes.
- Create 1.4 and 1.5 specific subclasses of XmlRpcSunHttpTransportFactory. These are the proper locations
  for your patches.

Steffen Pingel added a comment - 01/Aug/06 11:30 AM
I need per connection SSL support and proxy support for XmlRpcCommonsTransport. Once XmlRpcSunHttpTransport has been modified I can provide corresponding patches for the XmlRpcCommonsTransport.

Julio Francisco Veronelli added a comment - 01/Aug/06 05:07 PM
Thanks for the advice. Here's a patch and new files for the Sun transport. Now factories can be created directly or the most appropiate one can be created automatically. Ex:

XmlRpcTransport t = new XmlRpcSun14HttpTransport(pClient);

or,

XmlRpcTransport t = XmlRpcSunHttpTransport.getInstance(pClient);
if (t instanceof XmlRpcSun15HttpTransport) { /* set proxy or ssl factory */ }

Cheers.

Julio Francisco Veronelli added a comment - 01/Aug/06 07:36 PM
Sorry, the example is wrong, should read:

XmlRpcTransportFactory t = new XmlRpcSun14HttpTransportFactory(pClient);

or,

XmlRpcTransportFactory t = XmlRpcSunHttpTransportFactory.getInstance(pClient);
if (t instanceof XmlRpcSun15HttpTransportFactory) { /* set proxy or ssl factory */ }

As a sidenote, I'm not extending XmlRpcSunHttpTransportFactory from the other two factories, since they should be completely different factories from one another (and no unnecessary private fields are created). And as for features, methods can be added or deprecated from one version of Java SE to another, that's why XmlRpcSunHttp15TransportFactory does not extend from XmlRpcSun14HttpTransportFactory (same happens in XmlRpcSun15HttpTransport and XmlRpcSun14HttpTransport).

Cheers.

Jochen Wiedmann added a comment - 01/Aug/06 08:41 PM
Ok, I'll apply this patch (most possibly with slight modifications) after 3.0 is out.


Julio Francisco Veronelli added a comment - 02/Aug/06 02:27 AM
Ok, thanks a lot for your time and guidance.

Jochen Wiedmann added a comment - 27/Oct/07 07:47 PM
I have added the sunhttp.zip patches to the trunk.

Jochen Wiedmann added a comment - 27/Oct/07 08:16 PM
Applied the Lite transport specific changes as well.

Jochen Wiedmann added a comment - 28/Nov/08 08:53 PM
Closing issues which have been released.