[ http://issues.apache.org/jira/browse/XMLRPC-79?page=all ] Jochen Wiedmann closed XMLRPC-79: ---------------------------------
Resolution: Fixed Finally found out the deeper reason: The HTTP/1.0 specification requires a content-length header. As shown in Bugzilla 39508, there is a bug in Tomcat, which causes Tomcat to handle such requests incorrectly: Tomcat should simply refuse the request with an HTTP status code 400 (invalid). However, Tomcat accepts the request, but drops the request body. The absence of the request body explains the error message: The XML parser receives no data. As support of HTTP/1.1 with the Lite HTTP transport wouldn't be that easy (requires reading of chunked encoding on the client side), I have choosen to reject dropping the content-length header (and hence the support for gzip encoding) with the lite http transport. > Problems when enabling gzip compression > --------------------------------------- > > Key: XMLRPC-79 > URL: http://issues.apache.org/jira/browse/XMLRPC-79 > Project: XML-RPC > Type: Bug > Components: Releases > Versions: 3.0a1 > Environment: Linux Red Hat > Java 1.4.2 and 1.5(1.5.0_06) > Apache Tomcat 5.0.19, 5.5.9 > Reporter: Inaki Ortiz > Assignee: Jochen Wiedmann > Attachments: MyXmlRpcClient.java > > I am having problems when enabling the request/response compression > mode. I am using xmlrpc-3.0a1.jar for both my client and my server. In > the client I run the following: > config = new XmlRpcClientConfigImpl(); > config.setServerURL(serverURL); > // enables faster and memory saving streaming mode > config.setContentLengthOptional(true); > // enable vendor extensions to allow compression, data types support > ... > config.setEnabledForExtensions(true); > config.setGzipCompressing(true); // requests gzip compression > config.setGzipRequesting(true); // requests server to gzip response > > client = new XmlRpcClient(); > client.setConfig(config); > client.execute(...) > [...] > In the server I make use of the XmlRpcServlet class > (org.apache.xmlrpc.webserver package) embedded into Tomcat 5 and I have > set enabledForExtensions to true within the init parameters of the > servlet (web.xml file) > When I run a dummy request as it is described in the code above I get > the following exception: > org.apache.xmlrpc.XmlRpcException: Failed to parse XML-RPC request: > Content is not allowed in prolog. > at org.apache.xmlrpc.client.XmlRpcStreamTransport.readResponse > (XmlRpcStreamTransport.java:274) > at org.apache.xmlrpc.client.XmlRpcStreamTransport.sendRequest > (XmlRpcStreamTransport.java:216) > at org.apache.xmlrpc.client.XmlRpcClientWorker.execute > (XmlRpcClientWorker.java:53) > at org.apache.xmlrpc.client.XmlRpcClient.execute(XmlRpcClient.java:166) > at org.apache.xmlrpc.client.XmlRpcClient.execute(XmlRpcClient.java:136) > at org.apache.xmlrpc.client.XmlRpcClient.execute(XmlRpcClient.java:125) > at esavo.voql.xmlrpc.MyXmlRpcClient.execute(MyXmlRpcClient.java:54) > at esavo.voql.xmlrpc.MyXmlRpcClient.main(MyXmlRpcClient.java:74) > If I comment the gzip compression out, both on the request and the > response, my test works fine: > config = new XmlRpcClientConfigImpl(); > config.setServerURL(serverURL); > // enables faster and memory saving streaming mode > config.setContentLengthOptional(true); > // enable vendor extensions to allow compression, data types support > ... > config.setEnabledForExtensions(true); > client = new XmlRpcClient(); > client.setConfig(config); > client.execute(...) > [...] > The complete source code is the following: > 1. Client Side > ------------------------- > package esavo.voql.xmlrpc; > import java.net.URL; > import org.apache.xmlrpc.*; > import org.apache.xmlrpc.client.*; > /** > * MyXmlRpcClient > * @author Inaki Ortiz de Landaluce Saiz - ESAC/ESA - Madrid, Spain > */ > public class MyXmlRpcClient { > > /** XMLRpcClientConfig instance to specify serverURL, credentials ...etc > */ > private XmlRpcClientConfigImpl config; > /** The XmlRpcClient itself */ > private XmlRpcClient client; > > /** > * Creates a new instance of MyXmlRpcClient > */ > public MyXmlRpcClient(URL serverURL) { > // Step 1: Instances the client configuration and sets some properties > // N.B: This should be configurable through a xml or properties file > > config = new XmlRpcClientConfigImpl(); > config.setServerURL(serverURL); > // enables faster and memory saving streaming mode > config.setContentLengthOptional(true); > // enable vendor extensions to allow compression, data types support > ... > config.setEnabledForExtensions(true); > // it works fine when the following two lines are commented > config.setGzipCompressing(true); // requests gzip compression > config.setGzipRequesting(true); // requests server to gzip response > > // Step 2: Instances the client and atttaches the configuration to it > > client = new XmlRpcClient(); > client.setConfig(config); > // sets the fastest transport factory. > // There are several transport factories available: > // XmlRpcSunHttpTransportFactory - Uses default HTTP connection > // XmlRpcCommonsTransportFactory - Jakarta commons, lower memory > profile > // XmlRpcLiteHttpTransportFactory - Faster, does not support > HTTP/1.1</ul> > client.setTransportFactory(new > XmlRpcLiteHttpTransportFactory(client)); > } > > /** > * Executes an XML-RPC call > * @param methodName The method being performed. > * @param method The parameters. > * @return The result object > */ > public Object execute(String methodName, Object[] params) throws > XmlRpcException { > return client.execute(methodName, params); > } > > /** > * Returns XmlRpcClient instance > */ > public XmlRpcClient getClient() { > return client; > } > > public static void main(String[] args) { > String serverStr = "http://localhost:8084/VOQL-server/servlet/xmlrpc"; > try { > URL serverURL = new URL(serverStr); > MyXmlRpcClient client = new MyXmlRpcClient(serverURL); > > // full check disabled > Object[] params = new Object[]{new Boolean(false)}; > Boolean result = (Boolean) client.execute("Status.check", > params); > System.out.println("Result is " + result.toString()); > } catch (XmlRpcClientException e) { > e.printStackTrace(); > } catch (Exception e) { > e.printStackTrace(); > } > } > } > 2. Server Side > -------------------------- > 2.1 WAR configuration file (web.xml) > ------------------------------------------------------------------- > <?xml version="1.0" encoding="UTF-8"?> > <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" > xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" > xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee > http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> > <servlet> > <servlet-name>XmlRpcServlet</servlet-name> > > <servlet-class>org.apache.xmlrpc.webserver.XmlRpcServlet</servlet-class> > <init-param> > <param-name>enabledForExtensions</param-name> > <param-value>true</param-value> > </init-param> > </servlet> > <servlet-mapping> > <servlet-name>XmlRpcServlet</servlet-name> > <url-pattern>/servlet/xmlrpc</url-pattern> > </servlet-mapping> > <session-config> > <session-timeout> > 30 > </session-timeout> > </session-config> > <welcome-file-list> > <welcome-file> > index.jsp > </welcome-file> > </welcome-file-list> > </web-app> > 2.2 Handler > ----------------------- > package esavo.voql.server; > /** > * > * @author Inaki Ortiz de Landaluce Saiz - ESAC/ESA - Madrid, Spain > */ > public class Status { > > /** Creates a new instance of Status */ > public Status() { > } > > public boolean check(boolean fullCheck) { > // perform a full check on service availability. TBD > if(!fullCheck) return true; > else return false; > } > > } > 2.3 XmlRpcServlet.properties > ---------------------------------------------------- > Remote=org.apache.xmlrpc.test.BaseTest$Remote > Status=esavo.voql.server.Status -- This message is automatically generated by JIRA. - If you think it was sent incorrectly contact one of the administrators: http://issues.apache.org/jira/secure/Administrators.jspa - For more information on JIRA, see: http://www.atlassian.com/software/jira