XmlRpcCommonsTransportFactory ignores httpclient HostConfiguration while
creating PostMethod object
---------------------------------------------------------------------------------------------------
Key: XMLRPC-188
URL: https://issues.apache.org/jira/browse/XMLRPC-188
Project: XML-RPC
Issue Type: Bug
Components: Source
Affects Versions: 3.1.3
Reporter: Rafal Krzewski
I am trying to connect to XmlRpc server through SSL using a self signed
certificate.
For that I am using commons httpclient transport together with
AuthSSLProtocolSocketFactory from httpclient 3.1 contrib section.
Here's my setup code:
{code}
XmlRpcClientConfigImpl xmlRpcConfig = new XmlRpcClientConfigImpl();
xmlRpcConfig.setServerURL(serverUrl);
XmlRpcClient xmlRpcClient = new XmlRpcClient();
xmlRpcClient.setConfig(xmlRpcConfig);
ProtocolSocketFactory sslSocketFactory = new AuthSSLProtocolSocketFactory(null,
null, keyStoreUrl, keyStorePass);
Protocol protocol = new Protocol("https", sslSocketFactory,
serverUrl.getPort());
HttpClient httpClient = new HttpClient();
httpClient.getHostConfiguration().setHost(serverUrl.getHost(),
serverUrl.getPort(), protocol);
XmlRpcCommonsTransportFactory transportFactory = new
XmlRpcCommonsTransportFactory(xmlRpcClient);
transportFactory.setHttpClient(httpClient);
xmlRpcClient.setTransportFactory(transportFactory);
{code}
Unfortunately, when the request is being made,
XmlRpcCommonsTransport.newPostMethod(XmlRpcHttpClientConfig pConfig) is
executed and it creates the PostMethod object in the following way:
return new PostMethod(pConfig.getServerURL().toString());
When XmlRpcCommonsTransport.writeRequest(final ReqWriter pWriter) execution,
HttpClient.executeMethod(HttpMethod method) is invoked. It calls
HttpClient.executeMethod(HostConfiguration hostconfig, final HttpMethod method,
final HttpState state) with null hostconfig parameter. This combined with the
fact that PostMethod uri is absolute, causes hostconfig to be initialized from
scratch using the URI. Whatever host configuration was provided by the user
through HttpClient.getHostConfiguration().setHost(...) is ignored.
I am aware that I could override httpclient's protocol handler for https using
Protocol.registerProtocol(String id, Protocol protocol) call, but that would
have ClassLoader wide scope, which is not something a "good citizen"
application component should do.
In order to circumvent this issue I have subclassed XmlRpcCommonsTransport to
override PostMethod newPostMethod(XmlRpcHttpClientConfig pConfig) as follows:
{code}
protected PostMethod newPostMethod(XmlRpcHttpClientConfig pConfig)
{
HostConfiguration hostConfiguration = client.getHostConfiguration();
URL requestUrl = pConfig.getServerURL();
if(hostConfig != null)
{
if(requestUrl.getProtocol().equals(hostConfiguration.getProtocol().getScheme())
&& requestUrl.getHost().equals(hostConfiguration.getHost())
&& requestUrl.getPort() == hostConfiguration.getPort())
{
// use URI relative to base URI determined by HostConfiguration
return new PostMethod(requestUrl.getFile());
}
else
{
throw new IllegalArgumentException("Server URL " + requestUrl
+ "does not agree with HttpClient host configuration " +
hostConfiguration);
}
}
// use absolute URI
return new PostMethod(requestUrl.toString());
}
{code}
If the user bothered to set a custom HostConfiguration but used different
server base URL for the XmlRpcClient, the method throws an exception. I think
it'll help the user to spot the configuration error earlier.
Using this derived class (and matching XmlRpcCommonsTransportFactory) I was
able to connect to the server using SSL with self signed certificate loaded
from JKS keystore loaded into AuthSSLProtocolSocketFactory.
--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]