You are viewing a plain text version of this content. The canonical link for it is here.
Posted to soap-dev@xml.apache.org by sn...@apache.org on 2002/09/05 18:50:52 UTC
cvs commit: xml-soap/java/src/org/apache/soap/util/net HTTPUtils.java
snichol 2002/09/05 09:50:52
Modified: java/docs changes.html
java/src/org/apache/soap/rpc SOAPContext.java
java/src/org/apache/soap/server ServerUtils.java
ServiceManagerClient.java
java/src/org/apache/soap/server/http
MessageRouterServlet.java RPCRouterServlet.java
ServerHTTPUtils.java
java/src/org/apache/soap/transport TransportMessage.java
java/src/org/apache/soap/transport/http
SOAPHTTPConnection.java
java/src/org/apache/soap/util/net HTTPUtils.java
Added: java/samples/gzip DeploymentDescriptor.xml GzipClient.java
GzipService.java README testit.cmd testit.sh
Log:
Support gzip encoding for HTTP. This is enabled through SOAPContext
for clients and the deployment descriptor for services.
Revision Changes Path
1.44 +2 -0 xml-soap/java/docs/changes.html
Index: changes.html
===================================================================
RCS file: /home/cvs/xml-soap/java/docs/changes.html,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -r1.43 -r1.44
--- changes.html 30 Aug 2002 21:38:59 -0000 1.43
+++ changes.html 5 Sep 2002 16:50:51 -0000 1.44
@@ -74,6 +74,8 @@
document/literal encoding. Parameters will be serialized using document/literal
style. Return values must be mapped by parameter name (the existing
interop hack).</li>
+ <li>Support gzip encoding for HTTP. This is enabled through SOAPContext
+ for clients and the deployment descriptor for services.</li>
</ul>
</li>
</ul>
1.1 xml-soap/java/samples/gzip/DeploymentDescriptor.xml
Index: DeploymentDescriptor.xml
===================================================================
<isd:service xmlns:isd="http://xml.apache.org/xml-soap/deployment"
id="urn:gzip-sample">
<isd:provider type="java"
scope="Application"
methods="test">
<isd:java class="samples.gzip.GzipService"/>
<isd:option key="gzip" value="true"/>
<isd:option key="SessionRequired" value="false"/>
</isd:provider>
<isd:faultListener>org.apache.soap.server.DOMFaultListener</isd:faultListener>
</isd:service>
1.1 xml-soap/java/samples/gzip/GzipClient.java
Index: GzipClient.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "SOAP" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2000, International
* Business Machines, Inc., http://www.apache.org. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package samples.gzip;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.net.URL;
import java.util.Vector;
import org.apache.soap.*;
import org.apache.soap.rpc.*;
/**
* See README for info.
*
* @author Scott Nichol (snichol@computer.org)
*/
public class GzipClient {
public static void main (String[] args) throws Exception {
if (args.length != 3) {
System.err.println ("Usage: java " + GzipClient.class.getName() +
" SOAP-router-URL file-to-send file-to-receive");
System.exit(1);
}
// Process the arguments.
URL url = new URL(args[0]);
String inFileName = args[1];
String outFileName = args[2];
// Check that the output file does not exist
File outFile = new File(outFileName);
if (outFile.exists())
throw new Exception("File " + outFileName + " already exists.");
// Read the file to send
File inFile = new File(inFileName);
long inFileLength = inFile.length();
if (inFileLength > Integer.MAX_VALUE)
throw new Exception("File " + inFileName + " is too long ("
+ inFileLength + " bytes). Specify a file <= "
+ Integer.MAX_VALUE + " bytes.");
FileInputStream fis = new FileInputStream(inFile);
byte[] inFileData = new byte[(int) inFileLength];
int totalbytes = 0;
int bytes;
while ((totalbytes < inFileData.length) && (bytes = fis.read(inFileData, totalbytes, inFileData.length - totalbytes)) != -1) {
totalbytes += bytes;
}
fis.close();
System.out.println(totalbytes + " bytes read from " + inFileName + ".");
// Build the call.
SOAPContext ctx = new SOAPContext();
ctx.setGzip(true);
Vector params = new Vector();
params.addElement(new Parameter("data", inFileData.getClass(), inFileData, null));
Call call = new Call("urn:gzip-sample",
"test",
params,
null,
Constants.NS_URI_SOAP_ENC,
ctx);
// Invoke the call and handle the response.
Response resp = call.invoke(url, "");
if (resp.generatedFault()) {
Fault fault = resp.getFault();
System.err.println("Generated fault: " + fault);
} else {
Parameter result = resp.getReturnValue();
byte[] outFileData = (byte[]) result.getValue();
FileOutputStream fos = new FileOutputStream(outFileName);
fos.write(outFileData, 0, outFileData.length);
fos.close();
System.out.println(outFileData.length + " bytes written to " + outFileName + ".");
}
}
}
1.1 xml-soap/java/samples/gzip/GzipService.java
Index: GzipService.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "SOAP" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2000, International
* Business Machines, Inc., http://www.apache.org. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package samples.gzip;
/**
* Tests gzip.
*
* @author Scott Nichol (snichol@computer.org)
*/
public class GzipService {
/**
* Echoes a byte array after replacing the last 1024 bytes with 0x5a.
*/
public byte[] test(byte[] data) {
int offset = data.length > 1024 ? data.length - 1024 : 0;
while (offset < data.length)
data[offset++] = 0x5a;
return data;
}
}
1.1 xml-soap/java/samples/gzip/README
Index: README
===================================================================
Service:
-------
To install this service on an Apache-SOAP listener, you need to make
the samples.addressbook package available on the Apache-SOAP listener's
classpath. Then deploy this service by filling in the deployment
template using the info in the deployment descriptor in this
directory or by using the service manager client:
java org.apache.soap.server.ServiceManagerClient routerURL deploy dd.xml
where routerURL is the URL of the SOAP RPC router and dd.xml is the
name of the deployment descriptor file. For example:
java org.apache.soap.server.ServiceManagerClient \
http://localhost:8080/soap/servlet/rpcrouter deploy DeploymentDescriptor.xml
Client:
------
There is one HTTP client that sends the contents of a file as a byte array
and writes the response, which is an echo of the original file with the
last 1024 bytes changed to 0x5a, to a new file.
Additional Client Classpath Requirements:
----------------------------------------
../..
Explanation:
-----------
Basically an echo service, but configured with gzip encoding enabled on
both the client and the server.
Sample Usage:
------------
java samples.gzip.GzipClient \
http://localhost:8080/soap/servlet/rpcrouter GzipClient.java return.dat
1.1 xml-soap/java/samples/gzip/testit.cmd
Index: testit.cmd
===================================================================
@echo off
echo This test assumes a server URL of http://localhost:8080/soap/servlet/rpcrouter
echo Deploying the gzip service...
java org.apache.soap.server.ServiceManagerClient http://localhost:8080/soap/servlet/rpcrouter deploy DeploymentDescriptor.xml
echo .
echo Verify that it's there
java org.apache.soap.server.ServiceManagerClient http://localhost:8080/soap/servlet/rpcrouter list
echo .
echo Running the gzip test
del return.dat 2>nul
java samples.gzip.GzipClient http://localhost:8080/soap/servlet/rpcrouter GzipClient.java return.dat
echo .
echo Undeploy it now
java org.apache.soap.server.ServiceManagerClient http://localhost:8080/soap/servlet/rpcrouter undeploy urn:gzip-sample
echo .
echo Verify that it's gone
java org.apache.soap.server.ServiceManagerClient http://localhost:8080/soap/servlet/rpcrouter list
1.1 xml-soap/java/samples/gzip/testit.sh
Index: testit.sh
===================================================================
echo This test assumes a server URL of http://localhost:8080/soap/servlet/rpcrouter
echo Deploying the gzip service...
java org.apache.soap.server.ServiceManagerClient http://localhost:8080/soap/servlet/rpcrouter deploy DeploymentDescriptor.xml
echo
echo Verify that it\'s there
java org.apache.soap.server.ServiceManagerClient http://localhost:8080/soap/servlet/rpcrouter list
echo
echo Running the gzip test
rm return.dat
java samples.gzip.GzipClient http://localhost:8080/soap/servlet/rpcrouter GzipClient.java return.dat
echo
echo Undeploy it now
java org.apache.soap.server.ServiceManagerClient http://localhost:8080/soap/servlet/rpcrouter undeploy urn:gzip-sample
echo
echo Verify that it\'s gone
java org.apache.soap.server.ServiceManagerClient http://localhost:8080/soap/servlet/rpcrouter list
1.11 +40 -0 xml-soap/java/src/org/apache/soap/rpc/SOAPContext.java
Index: SOAPContext.java
===================================================================
RCS file: /home/cvs/xml-soap/java/src/org/apache/soap/rpc/SOAPContext.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- SOAPContext.java 30 Aug 2002 21:39:00 -0000 1.10
+++ SOAPContext.java 5 Sep 2002 16:50:51 -0000 1.11
@@ -87,6 +87,8 @@
protected Hashtable deserializedMultiRef = new Hashtable();
protected String currentId = null;
protected boolean docLitSerialization = false;
+ protected Boolean gzip = null;
+ protected Boolean acceptGzip = null;
/**
* This flag indicates if setRootPart() was called, so we can distinguish
@@ -597,6 +599,44 @@
*/
public void setDocLitSerialization(boolean docLitSerialization) {
this.docLitSerialization = docLitSerialization;
+ }
+
+ /**
+ * Gets whether gzip compression would be accepted.
+ *
+ * @return Whether gzip compression would be accepted.
+ * This is null if the value has not been set.
+ */
+ public Boolean getAcceptGzip() {
+ return acceptGzip;
+ }
+
+ /**
+ * Sets whether gzip compression would be accepted.
+ *
+ * @param Whether gzip compression would be accepted.
+ */
+ public void setAcceptGzip(boolean acceptGzip) {
+ this.acceptGzip = acceptGzip ? Boolean.TRUE : Boolean.FALSE;
+ }
+
+ /**
+ * Gets whether gzip compression is used in the byte array representation.
+ *
+ * @return Whether gzip compression is used in the byte array representation.
+ * This is null if the value has not been set.
+ */
+ public Boolean getGzip() {
+ return gzip;
+ }
+
+ /**
+ * Sets whether gzip compression is used in the byte array representation.
+ *
+ * @param gzip Whether gzip compression is used in the byte array representation.
+ */
+ public void setGzip(boolean gzip) {
+ this.gzip = gzip ? Boolean.TRUE : Boolean.FALSE;
}
/**
1.10 +67 -1 xml-soap/java/src/org/apache/soap/server/ServerUtils.java
Index: ServerUtils.java
===================================================================
RCS file: /home/cvs/xml-soap/java/src/org/apache/soap/server/ServerUtils.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- ServerUtils.java 2 May 2001 13:34:13 -0000 1.9
+++ ServerUtils.java 5 Sep 2002 16:50:52 -0000 1.10
@@ -68,6 +68,7 @@
import javax.xml.parsers.*;
import org.w3c.dom.* ;
import org.apache.soap.*;
+import org.apache.soap.encoding.soapenc.SoapEncUtils;
import org.apache.soap.rpc.*;
import org.apache.soap.server.http.*;
import org.apache.soap.util.*;
@@ -81,6 +82,7 @@
*
* @author Sanjiva Weerawarana
* @author Wouter Cloetens
+ * @author Scott Nichol (snichol@computer.org)
*/
public class ServerUtils {
/**
@@ -89,6 +91,12 @@
* transport level thing is wrong and throws a SOAPException if a
* SOAP level thing is wrong.
*
+ * @param xdb XML DOM document builder
+ * @param is Stream from which to read
+ * @param contentLength Length of message
+ * @param contentType Message content type, e.g. text/xml
+ * @param editor Hook to manipulate envelope
+ * @param ctx Context of current message
* @return Envelope containing the SOAP envelope found in the request
*
* @exception SOAPException if a SOAP level thing goes wrong
@@ -99,12 +107,42 @@
String contentType,
EnvelopeEditor editor,
SOAPContext ctx)
+ throws SOAPException, IOException,
+ IllegalArgumentException, MessagingException {
+ return readEnvelopeFromInputStream(xdb, is, contentLength, contentType,
+ editor, ctx, null);
+ }
+
+ /**
+ * Read in stuff from the request stream and return the envelope.
+ * Returns null (and sets the error on the response stream) if a
+ * transport level thing is wrong and throws a SOAPException if a
+ * SOAP level thing is wrong.
+ *
+ * @param xdb XML DOM document builder
+ * @param is Stream from which to read
+ * @param contentLength Length of message
+ * @param contentType Message content type, e.g. text/xml
+ * @param editor Hook to manipulate envelope
+ * @param ctx Context of current message
+ * @param headers Transport and/or MIME headers
+ * @return Envelope containing the SOAP envelope found in the request
+ *
+ * @exception SOAPException if a SOAP level thing goes wrong
+ */
+ public static Envelope readEnvelopeFromInputStream (DocumentBuilder xdb,
+ InputStream is,
+ int contentLength,
+ String contentType,
+ EnvelopeEditor editor,
+ SOAPContext ctx,
+ Hashtable headers)
throws SOAPException, IOException,
IllegalArgumentException, MessagingException {
// Read input stream.
TransportMessage reqMsg = new TransportMessage(is, contentLength,
contentType, ctx,
- null);
+ headers);
// Extract envelope and SOAPContext
reqMsg.read();
// Check Content-Type of root part of request to see if it's
@@ -121,6 +159,13 @@
return reqMsg.unmarshall(xdb);
}
+ /**
+ * Gets the Provider for the service in the deployment descriptor.
+ *
+ * @return Provider for the service in the deployment descriptor.
+ *
+ * @exception SOAPException if anything goes wrong
+ */
public static Provider loadProvider(DeploymentDescriptor dd,
SOAPContext ctxt)
throws SOAPException {
@@ -151,5 +196,26 @@
"'" + className + "' isn't a provider");
return (Provider)newObj;
+ }
+
+ /**
+ * Sets whether to gzip the response.
+ */
+ public static void setResponseGzip(DeploymentDescriptor dd,
+ SOAPContext reqCtx,
+ SOAPContext resCtx) {
+ if (Boolean.TRUE.equals(reqCtx.getAcceptGzip())) {
+ // Request specified gzip OK
+ Hashtable props = dd.getProps();
+ String gzip = props != null ? (String) props.get("gzip") : null;
+ resCtx.setGzip(gzip != null && SoapEncUtils.decodeBooleanValue(gzip));
+ } else if (Boolean.FALSE.equals(reqCtx.getAcceptGzip())) {
+ // Request specified gzip not OK
+ resCtx.setGzip(false);
+ } else {
+ // Request specified nothing, for now do not gzip
+ // TODO: should accept be required?
+ resCtx.setGzip(false);
+ }
}
}
1.10 +1 -2 xml-soap/java/src/org/apache/soap/server/ServiceManagerClient.java
Index: ServiceManagerClient.java
===================================================================
RCS file: /home/cvs/xml-soap/java/src/org/apache/soap/server/ServiceManagerClient.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- ServiceManagerClient.java 17 May 2001 18:25:52 -0000 1.9
+++ ServiceManagerClient.java 5 Sep 2002 16:50:52 -0000 1.10
@@ -130,8 +130,7 @@
if (resp.generatedFault ()) {
Fault fault = resp.getFault ();
System.out.println ("Ouch, the call failed: ");
- System.out.println (" Fault Code = " + fault.getFaultCode ());
- System.out.println (" Fault String = " + fault.getFaultString ());
+ System.out.println (fault.toString());
}
return resp;
}
1.36 +3 -1 xml-soap/java/src/org/apache/soap/server/http/MessageRouterServlet.java
Index: MessageRouterServlet.java
===================================================================
RCS file: /home/cvs/xml-soap/java/src/org/apache/soap/server/http/MessageRouterServlet.java,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -r1.35 -r1.36
--- MessageRouterServlet.java 4 Aug 2002 02:47:31 -0000 1.35
+++ MessageRouterServlet.java 5 Sep 2002 16:50:52 -0000 1.36
@@ -273,7 +273,8 @@
req.getContentType(),
req.getContentLength(),
req.getInputStream(),
- editor, res, reqCtx);
+ editor, res, reqCtx,
+ ServerHTTPUtils.getHeaders(req));
if (msgEnv == null)
return;
@@ -321,6 +322,7 @@
}
provider.locate( dd, msgEnv, null, messageName, targetID, reqCtx );
+ ServerUtils.setResponseGzip(dd, reqCtx, resCtx);
provider.invoke( reqCtx, resCtx );
sres = new TransportMessage(null, resCtx, null);
1.40 +3 -1 xml-soap/java/src/org/apache/soap/server/http/RPCRouterServlet.java
Index: RPCRouterServlet.java
===================================================================
RCS file: /home/cvs/xml-soap/java/src/org/apache/soap/server/http/RPCRouterServlet.java,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -r1.39 -r1.40
--- RPCRouterServlet.java 4 Aug 2002 02:47:31 -0000 1.39
+++ RPCRouterServlet.java 5 Sep 2002 16:50:52 -0000 1.40
@@ -316,7 +316,8 @@
req.getInputStream(),
editor,
res,
- reqCtx);
+ reqCtx,
+ ServerHTTPUtils.getHeaders(req));
if (callEnv == null)
return;
call = RPCRouter.extractCallFromEnvelope(serviceManager, callEnv,
@@ -367,6 +368,7 @@
provider.locate( dd, callEnv, call, call.getMethodName(), fullTargetID,
reqCtx );
+ ServerUtils.setResponseGzip(dd, reqCtx, resCtx);
provider.invoke( reqCtx, resCtx );
} catch (Throwable t) {
1.25 +55 -1 xml-soap/java/src/org/apache/soap/server/http/ServerHTTPUtils.java
Index: ServerHTTPUtils.java
===================================================================
RCS file: /home/cvs/xml-soap/java/src/org/apache/soap/server/http/ServerHTTPUtils.java,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -r1.24 -r1.25
--- ServerHTTPUtils.java 11 Jul 2002 15:45:53 -0000 1.24
+++ ServerHTTPUtils.java 5 Sep 2002 16:50:52 -0000 1.25
@@ -182,6 +182,13 @@
* transport level thing is wrong and throws a SOAPException if a
* SOAP level thing is wrong.
*
+ * @param xdb XML DOM document builder
+ * @param contentType Message content type, e.g. text/xml
+ * @param contentLength Length of message
+ * @param requestStream Stream from which to read
+ * @param editor Hook to manipulate envelope
+ * @param res Stream to which to write response in case of error
+ * @param ctx Context of current message
* @return Envelope containing the SOAP envelope found in the request
*
* @exception SOAPException if a SOAP level thing goes wrong
@@ -196,11 +203,44 @@
HttpServletResponse res,
SOAPContext ctx)
throws SOAPException, IOException {
+ return readEnvelopeFromRequest(xdb, contentType, contentLength,
+ requestStream, editor, res, ctx, null);
+ }
+
+ /**
+ * Read in stuff from the HTTP request stream and return the envelope.
+ * Returns null (and sets the error on the response stream) if a
+ * transport level thing is wrong and throws a SOAPException if a
+ * SOAP level thing is wrong.
+ *
+ * @param xdb XML DOM document builder
+ * @param contentType Message content type, e.g. text/xml
+ * @param contentLength Length of message
+ * @param requestStream Stream from which to read
+ * @param editor Hook to manipulate envelope
+ * @param res Stream to which to write response in case of error
+ * @param ctx Context of current message
+ * @param headers Transport and/or MIME headers
+ * @return Envelope containing the SOAP envelope found in the request
+ *
+ * @exception SOAPException if a SOAP level thing goes wrong
+ * @exception IOException if something fails while sending an
+ * error response
+ */
+ public static Envelope readEnvelopeFromRequest (DocumentBuilder xdb,
+ String contentType,
+ int contentLength,
+ InputStream requestStream,
+ EnvelopeEditor editor,
+ HttpServletResponse res,
+ SOAPContext ctx,
+ Hashtable headers)
+ throws SOAPException, IOException {
try {
return ServerUtils.readEnvelopeFromInputStream (xdb, requestStream,
contentLength,
contentType, editor,
- ctx);
+ ctx, headers);
} catch (IllegalArgumentException e) {
String msg = e.getMessage ();
res.sendError (res.SC_BAD_REQUEST, "Error unmarshalling envelope: " +
@@ -422,6 +462,20 @@
private static Hashtable getServiceParameters(DeploymentDescriptor dd) {
Hashtable props = dd.getProps();
return (props != null) ? (Hashtable) props.clone() : null;
+ }
+
+ /**
+ * Gets the HTTP headers for a request.
+ */
+ public static Hashtable getHeaders(HttpServletRequest req) {
+ Enumeration e = req.getHeaderNames();
+ Hashtable headers = new Hashtable(20);
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+ String value = req.getHeader(name);
+ headers.put(name, value);
+ }
+ return headers;
}
/**
1.15 +56 -0 xml-soap/java/src/org/apache/soap/transport/TransportMessage.java
Index: TransportMessage.java
===================================================================
RCS file: /home/cvs/xml-soap/java/src/org/apache/soap/transport/TransportMessage.java,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- TransportMessage.java 28 Aug 2002 18:32:28 -0000 1.14
+++ TransportMessage.java 5 Sep 2002 16:50:52 -0000 1.15
@@ -59,6 +59,8 @@
import java.io.*;
import java.util.*;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
import javax.activation.*;
import javax.mail.*;
import javax.mail.internet.*;
@@ -69,6 +71,7 @@
import org.apache.soap.encoding.*;
import org.apache.soap.rpc.*;
import org.apache.soap.util.*;
+import org.apache.soap.util.net.HTTPUtils;
import org.apache.soap.util.xml.*;
import org.apache.soap.util.mime.*;
import org.apache.soap.transport.EnvelopeEditor;
@@ -77,6 +80,7 @@
* Transport type-independent encapsulation of SOAP message content.
*
* @author Wouter Cloetens
+ * @author Scott Nichol (snichol@computer.org)
*/
public class TransportMessage implements Serializable {
protected String contentType = null;
@@ -215,6 +219,43 @@
if (cType == null)
throw new SOAPException(Constants.FAULT_CODE_PROTOCOL,
"Missing content type.");
+
+ // Check encoding
+ String encoding = (String) HTTPUtils.getHeaderValue(headers,
+ "Accept-Encoding");
+ if (encoding != null)
+ ctx.setAcceptGzip(encoding.indexOf("gzip") != -1);
+
+ encoding = (String) HTTPUtils.getHeaderValue(headers,
+ "Content-Encoding");
+ boolean gzip = false;
+ if (encoding != null && encoding.indexOf("gzip") != -1)
+ gzip = true;
+ ctx.setGzip(gzip);
+ if (gzip) {
+ // Inflate
+ ByteArrayInputStream bais =
+ new ByteArrayInputStream(bytes);
+ GZIPInputStream gzis = new GZIPInputStream(bais);
+ byte[] newbytes = new byte[bytes.length * 4];
+ int totalread = 0;
+ int bytesread;
+ while ((bytesread = gzis.read(newbytes, totalread,
+ newbytes.length - totalread)) != -1) {
+ totalread += bytesread;
+ if (totalread >= newbytes.length) {
+ byte[] newerbytes = new byte[totalread * 4];
+ System.arraycopy(newbytes, 0, newerbytes, 0, totalread);
+ newbytes = newerbytes;
+ }
+ }
+ gzis.close();
+ bais.close();
+ bytes = new byte[totalread];
+ System.arraycopy(newbytes, 0, bytes, 0, totalread);
+ }
+
+ // Start parsing
MimeBodyPart rootPart;
ContentType rootContentType;
byte[] rootBytes;
@@ -364,6 +405,21 @@
else
valuebuf.append((char)bytes[offset]);
}
+ }
+ // TODO: should not send for HTTP response
+ headers.put("Accept-Encoding", "x-gzip");
+ if (Boolean.TRUE.equals(ctx.getGzip())) {
+ // Deflate
+ ByteArrayOutputStream baos =
+ new ByteArrayOutputStream(bytes.length * 2);
+ GZIPOutputStream gzos = new GZIPOutputStream(baos);
+ gzos.write(bytes, offset, bytes.length - offset);
+ gzos.close();
+ baos.close();
+ bytes = baos.toByteArray();
+ offset = 0;
+
+ headers.put("Content-Encoding", "x-gzip");
}
}
1.26 +2 -22 xml-soap/java/src/org/apache/soap/transport/http/SOAPHTTPConnection.java
Index: SOAPHTTPConnection.java
===================================================================
RCS file: /home/cvs/xml-soap/java/src/org/apache/soap/transport/http/SOAPHTTPConnection.java,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -r1.25 -r1.26
--- SOAPHTTPConnection.java 30 Jul 2002 20:32:05 -0000 1.25
+++ SOAPHTTPConnection.java 5 Sep 2002 16:50:52 -0000 1.26
@@ -416,7 +416,7 @@
// Note: Header is case-insensitive
String hdr;
- hdr = getHeaderValue (responseHeaders, "Set-Cookie2");
+ hdr = HTTPUtils.getHeaderValue (responseHeaders, "Set-Cookie2");
if (hdr != null) {
Cookie[] hdrCookies = Cookie.parseCookies(sendTo, hdr);
@@ -426,7 +426,7 @@
cookies2 = hdrCookies;
}
- hdr = getHeaderValue (responseHeaders, "Set-Cookie");
+ hdr = HTTPUtils.getHeaderValue (responseHeaders, "Set-Cookie");
if (hdr != null) {
Cookie[] hdrCookies = Cookie.parseCookies(sendTo, hdr);
@@ -472,25 +472,5 @@
*/
public SOAPContext getResponseSOAPContext () {
return responseSOAPContext;
- }
-
- /**
- * Obtain a header value from the table using a case insensitive search.
- *
- * @param headers a colletion of headers from the http response
- * @param headerName the name of the header to find
- * @return the header value or null if not found
- */
- private static String getHeaderValue (Hashtable headers, String headerName)
- {
- for (Enumeration enum = headers.keys (); enum.hasMoreElements ();) {
- String key = (String) enum.nextElement();
-
- if (key.equalsIgnoreCase (headerName)) {
- return (String) headers.get(key);
- }
- }
-
- return null;
}
}
1.29 +18 -0 xml-soap/java/src/org/apache/soap/util/net/HTTPUtils.java
Index: HTTPUtils.java
===================================================================
RCS file: /home/cvs/xml-soap/java/src/org/apache/soap/util/net/HTTPUtils.java,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -r1.28 -r1.29
--- HTTPUtils.java 25 Jun 2002 21:23:53 -0000 1.28
+++ HTTPUtils.java 5 Sep 2002 16:50:52 -0000 1.29
@@ -132,6 +132,24 @@
}
/**
+ * Obtain a header value from the table using a case insensitive search.
+ *
+ * @param headers a colletion of headers from the http response
+ * @param headerName the name of the header to find
+ * @return the header value or null if not found
+ */
+ public static String getHeaderValue(Hashtable headers,
+ String headerName) {
+ for (Enumeration enum = headers.keys(); enum.hasMoreElements(); ) {
+ String key = (String) enum.nextElement();
+ if (key.equalsIgnoreCase(headerName)) {
+ return (String) headers.get(key);
+ }
+ }
+ return null;
+ }
+
+ /**
* Utility function to determine port number from URL object.
*
* @param url URL object from which to determine port number
--
To unsubscribe, e-mail: <ma...@xml.apache.org>
For additional commands, e-mail: <ma...@xml.apache.org>