* Fix NullPointerException in getAction() for 404 requests.
* Move XML-RPC response and error encoding to ResponseTrans class. * Implement error response generation for new type XML-RPC requests. * Set req.method to "XMLRPC" for new type XML-RPC requests.
This commit is contained in:
parent
8a30ebf693
commit
b7f0aa4ee2
3 changed files with 75 additions and 40 deletions
|
@ -59,7 +59,7 @@ public class RequestTrans implements Serializable {
|
|||
private final Map values;
|
||||
|
||||
// the HTTP request method
|
||||
private final String method;
|
||||
private String method;
|
||||
|
||||
// timestamp of client-cached version, if present in request
|
||||
private long ifModifiedSince = -1;
|
||||
|
@ -70,9 +70,6 @@ public class RequestTrans implements Serializable {
|
|||
// when was execution started on this request?
|
||||
private final long startTime;
|
||||
|
||||
// true if this might be an XML-RPC request
|
||||
private boolean isXmlRpc;
|
||||
|
||||
// the name of the action being invoked
|
||||
private String action;
|
||||
private String httpUsername;
|
||||
|
@ -101,9 +98,6 @@ public class RequestTrans implements Serializable {
|
|||
this.path = path;
|
||||
values = new SystemMap();
|
||||
startTime = System.currentTimeMillis();
|
||||
if ("POST".equals(method) && "text/xml".equals(request.getContentType())) {
|
||||
isXmlRpc = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -111,17 +105,19 @@ public class RequestTrans implements Serializable {
|
|||
*
|
||||
* @return true if this might be an XML-RPC request.
|
||||
*/
|
||||
public synchronized boolean isXmlRpc() {
|
||||
return isXmlRpc;
|
||||
public synchronized boolean checkXmlRpc() {
|
||||
return "POST".equals(method) && "text/xml".equals(request.getContentType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the isXmlRpc flag
|
||||
* Return true if this request is in fact handled as XML-RPC request.
|
||||
* This implies that {@link #checkXmlRpc()} returns true and a matching
|
||||
* XML-RPC action was found.
|
||||
*
|
||||
* @param xmlrpc true if this is infact an XML-RPC request
|
||||
* @return true if this request is handled as XML-RPC request.
|
||||
*/
|
||||
public synchronized void setXmlRpc(boolean xmlrpc) {
|
||||
isXmlRpc = xmlrpc;
|
||||
public synchronized boolean isXmlRpc() {
|
||||
return XMLRPC.equals(method);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -195,10 +191,19 @@ public class RequestTrans implements Serializable {
|
|||
* Return the method of the request. This may either be a HTTP method or
|
||||
* one of the Helma pseudo methods defined in this class.
|
||||
*/
|
||||
public String getMethod() {
|
||||
public synchronized String getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the method of this request.
|
||||
*
|
||||
* @param method the method.
|
||||
*/
|
||||
public synchronized void setMethod(String method) {
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this object represents a HTTP GET Request.
|
||||
*/
|
||||
|
|
|
@ -25,6 +25,8 @@ import java.io.*;
|
|||
import java.security.*;
|
||||
import java.util.*;
|
||||
|
||||
import org.apache.xmlrpc.XmlRpcResponseProcessor;
|
||||
|
||||
/**
|
||||
* A Transmitter for a response to the servlet client. Objects of this
|
||||
* class are directly exposed to JavaScript as global property res.
|
||||
|
@ -129,13 +131,6 @@ public final class ResponseTrans implements Serializable {
|
|||
Application app;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new ResponseTrans object.
|
||||
*/
|
||||
public ResponseTrans(Application app) {
|
||||
this.app = app;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new ResponseTrans object.
|
||||
*
|
||||
|
@ -462,6 +457,9 @@ public final class ResponseTrans implements Serializable {
|
|||
* @param message the error message
|
||||
*/
|
||||
public void writeErrorReport(String appName, String message) {
|
||||
if (reqtrans.isXmlRpc()) {
|
||||
writeXmlRpcError(new RuntimeException(message));
|
||||
} else {
|
||||
write("<html><body><h3>");
|
||||
write("Error in application ");
|
||||
write(appName);
|
||||
|
@ -469,6 +467,30 @@ public final class ResponseTrans implements Serializable {
|
|||
write(message);
|
||||
write("</body></html>");
|
||||
}
|
||||
}
|
||||
|
||||
public void writeXmlRpcResponse(Object result) {
|
||||
try {
|
||||
reset();
|
||||
contentType = "text/xml";
|
||||
if (charset == null) {
|
||||
charset = "UTF-8";
|
||||
}
|
||||
XmlRpcResponseProcessor xresproc = new XmlRpcResponseProcessor();
|
||||
writeBinary(xresproc.encodeResponse(result, charset));
|
||||
} catch (Exception x) {
|
||||
writeXmlRpcError(x);
|
||||
}
|
||||
}
|
||||
|
||||
public void writeXmlRpcError(Exception x) {
|
||||
contentType = "text/xml";
|
||||
if (charset == null) {
|
||||
charset = "UTF-8";
|
||||
}
|
||||
XmlRpcResponseProcessor xresproc = new XmlRpcResponseProcessor();
|
||||
writeBinary(xresproc.encodeException(x, charset));
|
||||
}
|
||||
|
||||
/**
|
||||
* This has to be called after writing to this response has finished and before it is shipped back to the
|
||||
|
|
|
@ -25,7 +25,6 @@ import java.util.*;
|
|||
|
||||
import org.apache.xmlrpc.XmlRpcRequestProcessor;
|
||||
import org.apache.xmlrpc.XmlRpcServerRequest;
|
||||
import org.apache.xmlrpc.XmlRpcResponseProcessor;
|
||||
|
||||
/**
|
||||
* This class does the work for incoming requests. It holds a transactor thread
|
||||
|
@ -194,7 +193,7 @@ public final class RequestEvaluator implements Runnable {
|
|||
String errorAction = app.props.getProperty("error",
|
||||
"error");
|
||||
|
||||
action = getAction(currentElement, errorAction, null);
|
||||
action = getAction(currentElement, errorAction, req);
|
||||
|
||||
if (action == null) {
|
||||
throw new RuntimeException(error);
|
||||
|
@ -284,7 +283,7 @@ public final class RequestEvaluator implements Runnable {
|
|||
"notfound");
|
||||
|
||||
currentElement = root;
|
||||
action = getAction(currentElement, notFoundAction, null);
|
||||
action = getAction(currentElement, notFoundAction, req);
|
||||
|
||||
if (action == null) {
|
||||
throw new FrameworkException(notfound.getMessage());
|
||||
|
@ -352,14 +351,11 @@ public final class RequestEvaluator implements Runnable {
|
|||
XmlRpcRequestProcessor xreqproc = new XmlRpcRequestProcessor();
|
||||
XmlRpcServerRequest xreq = xreqproc.decodeRequest(req.getServletRequest()
|
||||
.getInputStream());
|
||||
System.err.println("ARGUMENTS: " + xreq.getParameters());
|
||||
Vector args = xreq.getParameters();
|
||||
args.add(0, xreq.getMethodName());
|
||||
result = scriptingEngine.invoke(currentElement, action,
|
||||
args.toArray(), ScriptingEngine.ARGS_WRAP_XMLRPC);
|
||||
res.reset();
|
||||
XmlRpcResponseProcessor xresproc = new XmlRpcResponseProcessor();
|
||||
res.writeBinary(xresproc.encodeResponse(result, "UTF-8"));
|
||||
res.writeXmlRpcResponse(result);
|
||||
} else {
|
||||
scriptingEngine.invoke(currentElement, action,
|
||||
new Object[0],
|
||||
|
@ -533,7 +529,8 @@ public final class RequestEvaluator implements Runnable {
|
|||
|
||||
res.reset();
|
||||
|
||||
// check if we tried to process the error already
|
||||
// check if we tried to process the error already,
|
||||
// or if this is an XML-RPC request
|
||||
if (error == null) {
|
||||
app.errorCount += 1;
|
||||
|
||||
|
@ -555,6 +552,15 @@ public final class RequestEvaluator implements Runnable {
|
|||
|
||||
app.logError(txname + ": " + error, x);
|
||||
|
||||
if (req.isXmlRpc()) {
|
||||
// if it's an XML-RPC exception immediately generate error response
|
||||
if (!(x instanceof Exception)) {
|
||||
// we need an exception to pass to XML-RPC responder
|
||||
x = new Exception(x.toString(), x);
|
||||
}
|
||||
res.writeXmlRpcError((Exception) x);
|
||||
done = true;
|
||||
}
|
||||
} else {
|
||||
// error in error action. use traditional minimal error message
|
||||
res.writeErrorReport(app.getName(), error);
|
||||
|
@ -983,13 +989,15 @@ public final class RequestEvaluator implements Runnable {
|
|||
// afterwards for GET, POST, HEAD requests
|
||||
int length = buffer.length();
|
||||
|
||||
if (req.isXmlRpc()) {
|
||||
if (req.checkXmlRpc()) {
|
||||
// append _methodname
|
||||
buffer.append("_xmlrpc");
|
||||
if (scriptingEngine.hasFunction(obj, buffer.toString()))
|
||||
if (scriptingEngine.hasFunction(obj, buffer.toString())) {
|
||||
// handle as XML-RPC request
|
||||
req.setMethod(RequestTrans.XMLRPC);
|
||||
return buffer.toString();
|
||||
}
|
||||
// cut off method in case it has been appended
|
||||
req.setXmlRpc(false);
|
||||
buffer.setLength(length);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue