*) soap handler

- better errorhandling 
   - adding support for outgoing transfer- and content-encoding
   - avoid holding outgoing messages into memory before sending them

git-svn-id: https://svn.berlios.de/svnroot/repos/yacy/trunk@2872 6c8d7289-2bf4-0310-a012-ef5d649a1542
pull/1/head
theli 19 years ago
parent 5141fa5942
commit 532c23b5c7

@ -47,7 +47,7 @@ import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
final class httpChunkedOutputStream extends FilterOutputStream
public final class httpChunkedOutputStream extends FilterOutputStream
{
private boolean finished = false;
private static final byte[] crlf = {(byte)13,(byte)10};

@ -626,6 +626,7 @@ public final class httpHeader extends TreeMap implements Map {
args = args.substring(7);
sep = args.indexOf("/");
if (sep < 0) {
/*
// this is a malformed url, something like
// http://index.html
// we are lazy and guess that it means
@ -633,6 +634,9 @@ public final class httpHeader extends TreeMap implements Map {
// which is a localhost access to the file servlet
prop.setProperty(httpHeader.CONNECTION_PROP_HOST, virtualHost);
prop.setProperty(httpHeader.CONNECTION_PROP_PATH, "/" + args);
*/
prop.setProperty(httpHeader.CONNECTION_PROP_HOST, args);
prop.setProperty(httpHeader.CONNECTION_PROP_PATH, "/");
} else {
// THIS IS THE "GOOD" CASE
// a perfect formulated url
@ -659,6 +663,14 @@ public final class httpHeader extends TreeMap implements Map {
return prop;
}
public static boolean supportChunkedEncoding(Properties conProp) {
// getting the http version of the soap client
String httpVer = conProp.getProperty(httpHeader.CONNECTION_PROP_HTTP_VER);
// only clients with http version 1.1 supports chunk
return !(httpVer.equals(httpHeader.HTTP_VERSION_0_9) || httpVer.equals(httpHeader.HTTP_VERSION_1_0));
}
/**
* Reading http headers from a reader class and building up a httpHeader object
* @param reader the {@link BufferedReader} that is used to read the http header lines

@ -256,7 +256,7 @@ public final class httpd implements serverHandler {
// afterwards. In HTTP/1.1 (and above, in the future?) connections are
// persistent by default, but closed with the "Connection: close"
// property.
boolean persistent = !(httpVersion.equals("HTTP/0.9") || httpVersion.equals("HTTP/1.0"));
boolean persistent = !(httpVersion.equals(httpHeader.HTTP_VERSION_0_9) || httpVersion.equals(httpHeader.HTTP_VERSION_1_0));
if (((String)header.get(httpHeader.CONNECTION, "keep-alive")).toLowerCase().indexOf("close") != -1 ||
((String)header.get(httpHeader.PROXY_CONNECTION, "keep-alive")).toLowerCase().indexOf("close") != -1) {
persistent = false;
@ -1279,7 +1279,7 @@ public final class httpd implements serverHandler {
if (respond == null) throw new NullPointerException("The outputstream must not be null.");
if (conProp == null) throw new NullPointerException("The connection property structure must not be null.");
if (httpVersion == null) httpVersion = conProp.getProperty(httpHeader.CONNECTION_PROP_HTTP_VER,"HTTP/1.1");
if (httpVersion == null) httpVersion = conProp.getProperty(httpHeader.CONNECTION_PROP_HTTP_VER,httpHeader.HTTP_VERSION_1_1);
if (header == null) header = new httpHeader();
try {
@ -1294,7 +1294,7 @@ public final class httpd implements serverHandler {
StringBuffer headerStringBuffer = new StringBuffer(560);
// "HTTP/0.9" does not have a status line or header in the response
if (! httpVersion.toUpperCase().equals("HTTP/0.9")) {
if (! httpVersion.toUpperCase().equals(httpHeader.HTTP_VERSION_0_9)) {
// write status line
headerStringBuffer.append(httpVersion).append(" ")
.append(Integer.toString(httpStatusCode)).append(" ")

@ -45,7 +45,14 @@
package de.anomic.soap;
import javax.xml.namespace.QName;
import org.apache.axis.AxisFault;
import org.apache.axis.Constants;
import org.apache.axis.Message;
import org.apache.axis.MessageContext;
import org.apache.axis.message.SOAPEnvelope;
import org.apache.axis.message.SOAPFault;
import de.anomic.http.httpHeader;
@ -54,23 +61,41 @@ public class SoapException extends Exception {
private static final long serialVersionUID = 1L;
private int statusCode = 500;
private String statusText = (String) httpHeader.http1_1.get(Integer.toString(this.statusCode));
private Object errorMsg = this.statusText;
private AxisFault fault = new AxisFault(this.statusText);
public SoapException(int httpStatusCode, String httpStatusText, String errorMsg) {
super(httpStatusCode + " " + httpStatusText);
this.statusCode = httpStatusCode;
this.statusText = httpStatusText;
this.errorMsg = errorMsg;
this.fault = new AxisFault(errorMsg);
}
public SoapException(int httpStatusCode, String httpStatusText, Message errorMsg) {
public SoapException(int httpStatusCode, String httpStatusText, Exception e) {
super(httpStatusCode + " " + httpStatusText);
this.statusCode = httpStatusCode;
this.statusText = httpStatusText;
this.errorMsg = errorMsg;
}
this.statusText = httpStatusText;
// convert the exception into an axisfault
this.fault = AxisFault.makeFault(e);
}
public SoapException(AxisFault soapFault) {
QName faultCode = soapFault.getFaultCode();
if (Constants.FAULT_SOAP12_SENDER.equals(faultCode)) {
this.statusCode = 400;
this.statusText = "Bad request";
} else if ("Server.Unauthorized".equals(faultCode.getLocalPart())) {
this.statusCode = 401;
this.statusText = "Unauthorized";
} else {
this.statusCode = 500;
this.statusText = "Internal server error";
}
// convert the exception into an axisfault
this.fault = soapFault;
}
public int getStatusCode() {
return this.statusCode;
@ -80,7 +105,28 @@ public class SoapException extends Exception {
return this.statusText;
}
public Object getErrorMsg() {
return this.errorMsg;
public Object getFault() {
return this.fault;
}
public Message getFaultMessage(MessageContext msgContext) {
Message responseMsg = msgContext.getResponseMessage();
if (responseMsg == null) {
responseMsg = new Message(this.fault);
responseMsg.setMessageContext(msgContext);
} else {
try {
SOAPEnvelope env = responseMsg.getSOAPEnvelope();
env.clearBody();
env.addBodyElement(new SOAPFault(this.fault));
} catch (AxisFault e) {
// Should never reach here!
}
}
return responseMsg;
}
public String getMessage() {
return this.statusCode + " " + this.statusText;
}
}

@ -47,42 +47,39 @@ package de.anomic.soap;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PushbackInputStream;
import java.io.UnsupportedEncodingException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Properties;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import javax.xml.namespace.QName;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.soap.SOAPException;
import org.apache.axis.AxisFault;
import org.apache.axis.Constants;
import org.apache.axis.EngineConfiguration;
import org.apache.axis.Message;
import org.apache.axis.MessageContext;
import org.apache.axis.WSDDEngineConfiguration;
import org.apache.axis.deployment.wsdd.WSDDDeployment;
import org.apache.axis.deployment.wsdd.WSDDDocument;
import org.apache.axis.message.SOAPEnvelope;
import org.apache.axis.message.SOAPFault;
import org.apache.axis.server.AxisServer;
import org.apache.axis.utils.XMLUtils;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
import de.anomic.http.httpChunkedInputStream;
import de.anomic.http.httpChunkedOutputStream;
import de.anomic.http.httpContentLengthInputStream;
import de.anomic.http.httpHeader;
import de.anomic.http.httpc;
import de.anomic.http.httpd;
import de.anomic.http.httpdAbstractHandler;
import de.anomic.http.httpdHandler;
import de.anomic.plasma.plasmaParser;
@ -298,6 +295,7 @@ public final class httpdSoapHandler extends httpdAbstractHandler implements http
* Handle TRANSFER ENCODING
* =========================================================================== */
if (transferEncoding != null && !transferEncoding.equalsIgnoreCase("identity")) {
// read using transfer encoding
if (transferEncoding.equalsIgnoreCase("chunked")) {
input = new httpChunkedInputStream(body);
} else {
@ -306,8 +304,10 @@ public final class httpdSoapHandler extends httpdAbstractHandler implements http
throw new SoapException(501,"Not Implemented",errorMsg);
}
} else if (contentLength > 0) {
// read contentLength bytes
input = new httpContentLengthInputStream(body,contentLength);
} else {
// read until EOF
input = body;
}
@ -325,7 +325,7 @@ public final class httpdSoapHandler extends httpdAbstractHandler implements http
}
}
} catch (IOException e) {
throw new SoapException(400,"Bad Request",e.getMessage());
throw new SoapException(400,"Bad Request",e);
}
return input;
@ -340,8 +340,8 @@ public final class httpdSoapHandler extends httpdAbstractHandler implements http
*
* @see de.anomic.http.httpdHandler#doHead(java.util.Properties, de.anomic.http.httpHeader, java.io.OutputStream)
*/
public void doHead(Properties conProp, httpHeader header, OutputStream clientOut) throws IOException {
sendMessage(clientOut, 501, "Not Implemented", "Connection method is not supported by this handler",null);
public void doHead(Properties conProp, httpHeader requestHeader, OutputStream clientOut) throws IOException {
sendMessage(conProp, requestHeader, clientOut, 501, "Not Implemented", "Connection method is not supported by this handler",null);
conProp.setProperty(httpHeader.CONNECTION_PROP_PERSISTENT,"close");
}
@ -357,7 +357,7 @@ public final class httpdSoapHandler extends httpdAbstractHandler implements http
* @see de.anomic.http.httpdHandler#doConnect(java.util.Properties, de.anomic.http.httpHeader, java.io.InputStream, java.io.OutputStream)
*/
public void doConnect(Properties conProp, httpHeader requestHeader, InputStream clientIn, OutputStream clientOut) throws IOException {
sendMessage(clientOut, 501, "Not Implemented", "Connection method is not supported by this handler",null);
sendMessage(conProp, requestHeader, clientOut, 501, "Not Implemented", "Connection method is not supported by this handler",null);
conProp.setProperty(httpHeader.CONNECTION_PROP_PERSISTENT,"close");
}
@ -374,18 +374,14 @@ public final class httpdSoapHandler extends httpdAbstractHandler implements http
* @see de.anomic.http.httpdHandler#doGet(java.util.Properties, de.anomic.http.httpHeader, java.io.OutputStream)
*/
public void doGet(Properties conProp, httpHeader requestHeader, OutputStream response) throws IOException {
MessageContext msgContext = null;
String path = conProp.getProperty(httpHeader.CONNECTION_PROP_PATH);
try {
MessageContext msgContext = this.generateMessageContext(path, requestHeader, conProp);
// generating message context
msgContext = this.generateMessageContext(path, requestHeader, conProp);
Document doc = null;
try {
engine.generateWSDL(msgContext);
doc = (Document) msgContext.getProperty("WSDL");
} catch (AxisFault ex) {
Message errorMsg = faultToMessage(null, msgContext, ex);
throw new SoapException(500,"Unable to generate WSDL",errorMsg);
}
// generating wsdl file
Document doc = generateWSDL(msgContext);
if (doc != null) {
// Converting the the wsdl document into a byte-array
@ -393,30 +389,22 @@ public final class httpdSoapHandler extends httpdAbstractHandler implements http
byte[] result = responseDoc.getBytes("UTF-8");
// send back the result
sendMessage(response, 200, "OK", "text/xml; charset=utf-8", result);
sendMessage(conProp, requestHeader, response, 200, "OK", "text/xml; charset=utf-8", result);
if (!(requestHeader.get("Connection", "close").equals("keep-alive"))) {
if (!(requestHeader.get(httpHeader.CONNECTION, "close").equals("keep-alive"))) {
// wait a little time until everything closes so that clients can read from the streams/sockets
try {Thread.currentThread().join(200);} catch (InterruptedException e) {/* ignore this */}
}
} else {
// if we where unable to generate the wsdl file ....
String errorMsg = "Internal Server Error: Unable to generate the WSDL file.";
sendMessage(response, 500, "Internal Error", "text/plain",errorMsg.getBytes("UTF-8"));
sendMessage(conProp, requestHeader, response, 500, "Internal Error", "text/plain",errorMsg.getBytes("UTF-8"));
}
return;
} catch (SoapException e) {
try {
sendSoapException(response, e);
} catch (Exception ex) {
this.theLogger.logSevere("Unexpected Exception while sending error message",e);
} finally {
conProp.setProperty(httpHeader.CONNECTION_PROP_PERSISTENT,"close");
}
} catch (Exception e) {
conProp.setProperty(httpHeader.CONNECTION_PROP_PERSISTENT,"close");
this.theLogger.logSevere("Unexpected Exception with query: " + path,e);
// handle error
handleException(conProp,requestHeader,msgContext,response,e);
}
}
@ -428,11 +416,11 @@ public final class httpdSoapHandler extends httpdAbstractHandler implements http
* @param response {@link OutputStream} to the client
* @param body the request body containing the SOAP message
*
* @throws IOException
*
* @see de.anomic.http.httpdHandler#doPost(java.util.Properties, de.anomic.http.httpHeader, java.io.OutputStream, java.io.PushbackInputStream)
*/
public void doPost(Properties conProp, httpHeader requestHeader, OutputStream response, PushbackInputStream body) throws IOException {
public void doPost(Properties conProp, httpHeader requestHeader, OutputStream response, PushbackInputStream body) {
MessageContext msgContext = null;
String path = conProp.getProperty(httpHeader.CONNECTION_PROP_PATH);
try {
/* ========================================================================
@ -442,7 +430,7 @@ public final class httpdSoapHandler extends httpdAbstractHandler implements http
InputStream bodyStream = getBodyInputStream(requestHeader, body);
// generating the SOAP message context that will be passed over to the invoked service
MessageContext msgContext = this.generateMessageContext(path, requestHeader, conProp);
msgContext = this.generateMessageContext(path, requestHeader, conProp);
// Generating a SOAP Request Message Object
String mime = plasmaParser.getRealMimeType(requestHeader.mime()); // this is important !!!!
@ -461,84 +449,69 @@ public final class httpdSoapHandler extends httpdAbstractHandler implements http
Message responseMsg = this.invokeService(msgContext);
if (responseMsg != null) {
sendMessage(response, 200, "OK", responseMsg);
sendMessage(conProp, requestHeader, response, 200, "OK", responseMsg);
} else {
sendMessage(response, 202, "Accepted", "text/plain", null);
sendMessage(conProp, requestHeader, response, 202, "Accepted", "text/plain", null);
}
return;
} catch (SoapException e) {
try {
sendSoapException(response, e);
} catch (Exception ex) {
this.theLogger.logSevere("Unexpected Exception while sending error message",e);
} finally {
conProp.setProperty(httpHeader.CONNECTION_PROP_PERSISTENT,"close");
}
} catch (Exception e) {
conProp.setProperty(httpHeader.CONNECTION_PROP_PERSISTENT,"close");
this.theLogger.logSevere("Unexpected Exception",e);
// handle error
handleException(conProp, requestHeader, msgContext, response,e);
}
}
private void handleException(Properties conProp, httpHeader requestHeader, MessageContext messageContext, OutputStream response, Exception e) {
try {
Message soapErrorMsg = null;
if (!conProp.containsKey(httpHeader.CONNECTION_PROP_PROXY_RESPOND_HEADER)) {
SoapException soapEx = null;
if (!(e instanceof SoapException)) {
soapEx = new SoapException(500,"internal server error",e);
} else {
soapEx = (SoapException) e;
}
// generating a soap error message
soapErrorMsg = soapEx.getFaultMessage(messageContext);
// send error message back to the client
sendMessage(conProp,requestHeader,response,soapEx.getStatusCode(),soapEx.getStatusText(),soapErrorMsg);
} else {
this.theLogger.logSevere("Unexpected Exception while sending data to client",e);
}
} catch (Exception ex) {
this.theLogger.logSevere("Unexpected Exception while sending error message",e);
} finally {
conProp.setProperty(httpHeader.CONNECTION_PROP_PERSISTENT,"close");
}
}
private Document generateWSDL(MessageContext msgContext) throws SoapException {
try {
engine.generateWSDL(msgContext);
Document doc = (Document) msgContext.getProperty("WSDL");
return doc;
} catch (Exception ex) {
if (ex instanceof AxisFault) throw new SoapException((AxisFault)ex);
throw new SoapException(500,"Unable to generate WSDL",ex);
}
}
protected Message invokeService(MessageContext msgContext) throws SoapException {
int invocationStatusCode = 200;
String invocationStatusText = "OK";
try {
// invoke the service
engine.invoke(msgContext);
// Retrieve the response from Axis
return msgContext.getResponseMessage();
} catch (Exception ex) {
Message errorMsg;
AxisFault soapFault;
if (ex instanceof AxisFault) {
soapFault = (AxisFault) ex;
QName faultCode = soapFault.getFaultCode();
if (Constants.FAULT_SOAP12_SENDER.equals(faultCode)) {
invocationStatusCode = 400;
invocationStatusText = "Bad request";
} else if ("Server.Unauthorized".equals(faultCode.getLocalPart())) {
invocationStatusCode = 401;
invocationStatusText = "Unauthorized";
} else {
invocationStatusCode = 500;
invocationStatusText = "Internal server error";
}
} else {
invocationStatusCode = 500;
invocationStatusText = "Internal server error";
soapFault = AxisFault.makeFault(ex);
}
// There may be headers we want to preserve in the
// response message - so if it's there, just add the
// FaultElement to it. Otherwise, make a new one.
errorMsg = msgContext.getResponseMessage();
errorMsg = faultToMessage(errorMsg, msgContext, soapFault);
throw new SoapException(invocationStatusCode,invocationStatusText,errorMsg);
} catch (Exception ex) {
if (ex instanceof AxisFault) throw new SoapException((AxisFault)ex);
throw new SoapException(500,"Unable to invoke service",ex);
}
}
protected Message faultToMessage(Message errorMsg, MessageContext msgContext, AxisFault soapFault) {
Message theErrorMsg = errorMsg;
if (theErrorMsg == null) {
theErrorMsg = new Message(soapFault);
theErrorMsg.setMessageContext(msgContext);
} else {
try {
SOAPEnvelope env = theErrorMsg.getSOAPEnvelope();
env.clearBody();
env.addBodyElement(new SOAPFault(soapFault));
} catch (AxisFault fault) {
// Should never reach here!
}
}
return theErrorMsg;
}
/**
* This function deplays all java classes that should be available via SOAP call.
@ -636,8 +609,9 @@ public final class httpdSoapHandler extends httpdAbstractHandler implements http
msgContext.setTargetService(serviceName);
return msgContext;
} catch (AxisFault e) {
throw new SoapException(500,"Unable to set the target service",e.getMessage());
} catch (Exception e) {
if (e instanceof AxisFault) throw new SoapException((AxisFault)e);
throw new SoapException(500,"Unable to generate message context",e);
}
}
@ -666,79 +640,102 @@ public final class httpdSoapHandler extends httpdAbstractHandler implements http
return result;
}
protected void sendSoapException(OutputStream out, SoapException e) throws UnsupportedEncodingException, IOException, SOAPException {
Object errorMsg = e.getErrorMsg();
String contentType = null;
// getting the error message body and content length
ByteArrayOutputStream bout = new ByteArrayOutputStream();
if (errorMsg instanceof String) {
bout.write(((String)errorMsg).getBytes("UTF-8"));
contentType = "text/plain; charset=UTF-8";
} else {
Message soapErrorMsg = (Message)errorMsg;
soapErrorMsg.writeTo(bout);
contentType = soapErrorMsg.getContentType(soapErrorMsg.getMessageContext().getSOAPConstants());
}
// send out the message
sendMessage(out, e.getStatusCode(), e.getStatusText(), contentType, bout.toByteArray());
}
// protected void sendException(Properties conProp, OutputStream out, Exception e) throws UnsupportedEncodingException, IOException, SOAPException {
//
// Message soapErrorMsg = null;
// if (e instanceof SoapException) {
// Object errorMsg = ((SoapException)e).getErrorMsg();
// String contentType = null;
//
// // getting the error message body and content length
// ByteArrayOutputStream bout = new ByteArrayOutputStream();
// if (errorMsg instanceof String) {
// bout.write(((String)errorMsg).getBytes("UTF-8"));
// contentType = "text/plain; charset=UTF-8";
// } else {
// Message soapErrorMsg = (Message)errorMsg;
// soapErrorMsg.writeTo(bout);
// contentType = soapErrorMsg.getContentType(soapErrorMsg.getMessageContext().getSOAPConstants());
// }
// }
//
// // send out the message
// sendMessage(conProp, out, e.getStatusCode(), e.getStatusText(), contentType, bout.toByteArray());
// }
protected void sendMessage(OutputStream out, int statusCode, String statusText, String contentType, byte[] MessageBody) throws IOException {
protected void sendMessage(Properties conProp, httpHeader requestHeader, OutputStream out, int statusCode, String statusText, String contentType, byte[] MessageBody) throws IOException {
// write out the response header
respondHeader(out, statusCode, statusText, (MessageBody==null)?null:contentType, (MessageBody==null)?-1:MessageBody.length);
respondHeader(conProp, out, statusCode, statusText, (MessageBody==null)?null:contentType, (MessageBody==null)?-1:MessageBody.length, null, null);
// write the message body
if (MessageBody != null) out.write(MessageBody);
out.flush();
}
protected void sendMessage(OutputStream out, int statusCode, String statusText, Message soapMessage) throws IOException, SoapException {
// getting the content body
ByteArrayOutputStream bout = new ByteArrayOutputStream();
try {
soapMessage.writeTo(bout);
} catch (SOAPException e) {
throw new SoapException(500,"Unable to externalize SOAP message",e.getMessage());
}
protected void sendMessage(Properties conProp, httpHeader requestHeader, OutputStream out, int statusCode, String statusText, Message soapMessage) throws IOException, SOAPException {
httpChunkedOutputStream chunkedOut = null;
GZIPOutputStream gzipOut = null;
OutputStream bodyOut = out;
// getting the content type
String contentType = null;
try {
contentType = soapMessage.getContentType(soapMessage.getMessageContext().getSOAPConstants());
} catch (AxisFault e) {
throw new SoapException(500,"Unable to get content-type for SOAP message",e.getMessage());
String contentType = soapMessage.getContentType(soapMessage.getMessageContext().getSOAPConstants());
// getting the content length
String transferEncoding = null;
String contentEncoding = null;
long contentLength = -1;
if (httpHeader.supportChunkedEncoding(conProp)) {
transferEncoding = "chunked";
} else {
contentLength = soapMessage.getContentLength();
}
if (requestHeader.acceptGzip()) {
contentEncoding = "gzip";
}
// sending the soap header
respondHeader(conProp, out, statusCode, statusText, contentType, contentLength, contentEncoding, transferEncoding);
if (transferEncoding != null) bodyOut = chunkedOut = new httpChunkedOutputStream(bodyOut);
if (contentEncoding != null) bodyOut = gzipOut = new GZIPOutputStream(bodyOut);
// sending the message
sendMessage(out, statusCode, statusText, contentType, bout.toByteArray());
// sending the body
soapMessage.writeTo(bodyOut);
bodyOut.flush();
if (gzipOut != null) {
gzipOut.flush();
gzipOut.finish();
}
if (chunkedOut != null) {
chunkedOut.finish();
}
}
/**
* This method was copied from {@link httpdFileHandler}. Maybe it would be a good idea
* to move this function up into {@link httpdAbstractHandler}
*
* @param out the {@link OutputStream} to the client
* @param retcode the http code
* @param conttype the content type and encoding
* @param contlength the content length
* @throws IOException
*/
protected void respondHeader(OutputStream out, int retcode, String returnStatus, String conttype, long contlength) throws IOException {
try {
out.write(("HTTP/1.1 " + retcode + " " + returnStatus + "\r\n").getBytes());
out.write(("Server: AnomicHTTPD (www.anomic.de)\r\n").getBytes());
out.write(("Date: " + httpc.dateString(httpc.nowDate()) + "\r\n").getBytes());
if (conttype != null) out.write((httpHeader.CONTENT_TYPE + ": " + conttype + "\r\n").getBytes());
if (contlength != -1) out.write((httpHeader.CONTENT_LENGTH + ": " + contlength +"\r\n").getBytes());
out.write(("\r\n").getBytes());
out.flush();
} catch (Exception e) {
// any interruption may be caused be network error or because the user has closed
// the windows during transmission. We simply pass it as IOException
throw new IOException(e.getMessage());
}
protected void respondHeader(
Properties conProp,
OutputStream respond,
int httpStatusCode,
String httpStatusText,
String conttype,
long contlength,
String contentEncoding,
String transferEncoding
) throws IOException {
httpHeader outgoingHeader = new httpHeader();
outgoingHeader.put(httpHeader.SERVER,"AnomicHTTPD (www.anomic.de)");
if (conttype != null) outgoingHeader.put(httpHeader.CONTENT_TYPE,conttype);
if (contlength != -1) outgoingHeader.put(httpHeader.CONTENT_LENGTH, Long.toString(contlength));
if (contentEncoding != null) outgoingHeader.put(httpHeader.CONTENT_ENCODING, contentEncoding);
if (transferEncoding != null) outgoingHeader.put(httpHeader.TRANSFER_ENCODING, transferEncoding);
// getting the http version of the soap client
String httpVer = conProp.getProperty(httpHeader.CONNECTION_PROP_HTTP_VER);
// sending http headers
httpd.sendRespondHeader(conProp,respond,httpVer,httpStatusCode,httpStatusText,outgoingHeader);
}
}

@ -158,7 +158,15 @@ public class ShareService extends AbstractService {
private File getWorkingFile(File workingDir, String workingFileName) throws AxisFault, IOException {
if (workingDir == null) throw new NullPointerException("Working dir is null");
// getting file-share directory
File share = getShareDir();
// check filename for illegal characters
if (workingFileName != null) {
if ((workingFileName.indexOf("/") != -1) || (workingFileName.indexOf("/") != -1))
throw new AxisFault("Filename contains illegal characters.");
}
File workingFile = (workingFileName==null)?workingDir:new File(workingDir, workingFileName);
if (workingFile.getAbsolutePath().length() > serverSystem.maxPathLength)

@ -4,16 +4,17 @@ import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.rmi.Remote;
import java.util.Hashtable;
import java.util.Properties;
import javax.xml.rpc.ServiceException;
import org.apache.axis.client.Stub;
import yacy.soap.status.StatusService;
import yacy.soap.status.StatusServiceServiceLocator;
import junit.framework.TestCase;
import org.apache.axis.MessageContext;
import org.apache.axis.client.Stub;
import org.apache.axis.transport.http.HTTPConstants;
public abstract class AbstractServiceTest extends TestCase {
protected static final String SOAP_HEADER_NAMESPACE = "http://http.anomic.de/header";
protected static final String SOAP_HEADER_AUTHORIZATION = "Authorization";
@ -23,7 +24,7 @@ public abstract class AbstractServiceTest extends TestCase {
protected static Remote service;
protected void setUp() throws Exception {
if (peerPort == null) this.loadConfigProperties();
this.loadConfigProperties();
super.setUp();
}
@ -57,6 +58,14 @@ public abstract class AbstractServiceTest extends TestCase {
// setting the authentication header
((Stub)service).setHeader(SOAP_HEADER_NAMESPACE,SOAP_HEADER_AUTHORIZATION,authString);
// configure axis to use HTTP 1.1
((Stub)service)._setProperty(MessageContext.HTTP_TRANSPORT_VERSION,HTTPConstants.HEADER_PROTOCOL_V11);
// configure axis to use chunked transfer encoding
Hashtable userHeaderTable = new Hashtable();
userHeaderTable.put(HTTPConstants.HEADER_TRANSFER_ENCODING, HTTPConstants.HEADER_TRANSFER_ENCODING_CHUNKED);
((Stub)service)._setProperty(HTTPConstants.REQUEST_HEADERS,userHeaderTable);
} catch (Exception e) {
e.printStackTrace();
} finally {

@ -0,0 +1,18 @@
package de.anomic.soap.services;
import junit.framework.Test;
import junit.framework.TestSuite;
public class ServiceTests {
public static Test suite() {
TestSuite suite = new TestSuite("Test for de.anomic.soap.services");
//$JUnit-BEGIN$
suite.addTestSuite(ShareServiceTest.class);
suite.addTestSuite(StatusServiceTest.class);
suite.addTestSuite(BlacklistServiceTest.class);
//$JUnit-END$
return suite;
}
}

@ -1,7 +1,6 @@
package de.anomic.soap.services;
import java.io.IOException;
import java.rmi.RemoteException;
import java.util.Date;
import javax.activation.DataHandler;
@ -15,10 +14,9 @@ import org.apache.axis.client.Stub;
import org.apache.axis.utils.XMLUtils;
import org.w3c.dom.Document;
import de.anomic.server.serverFileUtils;
import yacy.soap.share.ShareService;
import yacy.soap.share.ShareServiceServiceLocator;
import de.anomic.server.serverFileUtils;
public class ShareServiceTest extends AbstractServiceTest {

Loading…
Cancel
Save