try {
if (actionType == null) {
log(getInfo(req, true, true) + "Missing ActionType, ignoring request");
String msg = getText(req, "noActionType", "Invalid access", null, null);
cleanupSession(req);
throw new XmlBlasterException(Global.instance(), ErrorCode.USER_ILLEGALARGUMENT,
"AjaxServlet", msg);
}
if (isBlockedIP(req.getRemoteAddr())) {
log(getInfo(req, true, true) + "Blocked IP " + req.getRemoteAddr() + ", ignoring request");
String msg = getText(req, "isBlocked", "Access is currently not allowed", null, null);
cleanupSession(req);
throw new XmlBlasterException(Global.instance(), ErrorCode.USER_SECURITY_AUTHENTICATION_ACCESSDENIED,
"AjaxServlet", msg);
}
//String host = req.getRemoteAddr();
//String ME = "AjaxServlet.doGet(" + host + "): ";
//log.info("ENTERING DOGET ....");
if (forceLoad)
log(getInfo(req) + "forceLoad=" + forceLoad);
if (req.getSession(false) == null) {
if (maxUserSessionsReached(req)) { // "?admin=true" will ignore this test
log(getInfo(req, true, true) + "Max user sessions = " + getMaxUserSessions() + " reached, please try again later");
String msg = getText(req, "maxUserSessionReached", "Max user sessions = {0} reached, please try again later",
""+getMaxUserSessions(), null);
throw new XmlBlasterException(Global.instance(), ErrorCode.USER_CONFIGURATION_MAXSESSION,
"AjaxServlet", msg);
}
HttpSession session = req.getSession(true);
session.setMaxInactiveInterval(this.maxInactiveInterval);
newBrowser = true;
log(getInfo(req, true, false) + "New browser arrived");
}
/*
}
catch (XmlBlasterException ex) {
res.setContentType("text/xml; charset=UTF-8");
PrintWriter backToBrowser = res.getWriter();
StringBuffer sb = new StringBuffer(512);
sb.append("<xmlBlasterResponse>");
sb.append(ex.toXml());
sb.append("</xmlBlasterResponse>");
backToBrowser.write(sb.toString());
backToBrowser.close();
return;
}
*/
// set header field first
//res.setContentType("text/plain; charset=UTF-8");
// xml header don't like empty response, so send at least "<void/>
//res.setContentType("text/xml; charset=UTF-8");
blasterInstance = getBlasterInstance(req);
boolean admin = getReqProp(req, "admin", false);
if (admin) blasterInstance.setAdmin(admin); // can be passed on connect()
if (actionType.equals("xmlScript")) {
String xmlScript64 = (String) req.getParameter("xmlScriptBase64");
String xmlScriptPlain = (String) req.getParameter("xmlScriptPlain");
byte[] raw = null;
if (xmlScript64 != null && xmlScriptPlain != null) {
String errTxt = "You can not set both 'xmlScriptBase64' and 'xmlScriptPlain'";
throw new XmlBlasterException(Global.instance(), ErrorCode.USER_ILLEGALARGUMENT, "AjaxServlet", errTxt);
}
String xmlScript = xmlScriptPlain;
if (xmlScript64 != null) {
// the url encoder has somewhere changed my + to blanks
// you must send this by invoking encodeURIComponent(txt) on the javascript side.
xmlScript64 = ReplaceVariable.replaceAll(xmlScript64, " ", "+");
raw = Base64.decode(xmlScript64);
xmlScript = new String(raw, "UTF-8");
} else if (xmlScriptPlain != null) {
raw = xmlScriptPlain.getBytes();
} else {
String errTxt = "You must choose one of 'xmlScriptBase64' and 'xmlScriptPlain' since you choosed 'xmlScript'";
throw new XmlBlasterException(Global.instance(), ErrorCode.USER_ILLEGALARGUMENT, "AjaxServlet", errTxt);
}
if (newBrowser && xmlScript.indexOf("<connect")==-1)
throw new XmlBlasterException(Global.instance(), ErrorCode.USER_ILLEGALARGUMENT, "AjaxServlet", "The first call must contain a connect markup");
blasterInstance.execute(raw, xmlScript, out);
return;
}
// A request/reply with direct binary streaming of the MsgUnit content
// back to the browser, can be used e.g. to access backend DB pictures
// Todo: Add a variant with service response, e.g. &binary=false
// "/watchee/ajax?ActionType=request&task=getRawPhoto&data=4517&timeout=5000&maxEntries=10"
else if (actionType.equals("request")) { // request-response pattern, blocking for repsonse
// "image/gif" "image/jpeg" "image/bmp" "image/x-png" "application/x-msdownload" "video/avi" "video/mpeg"
long timeout = (req.getParameter("timeout") == null) ? 8000 : Long.valueOf(
(String) req.getParameter("timeout")).longValue();
int maxEntries = (req.getParameter("maxEntries") == null) ? 1 : Integer.valueOf(
(String) req.getParameter("maxEntries")).intValue();
String topicId = (req.getParameter("topicId") == null) ? "service" : (String) req
.getParameter("topicId");
String content = req.getParameter("content");
String qos = (req.getParameter("qos") == null) ? "<qos/>" : (String) req
.getParameter("qos");
if (content == null) {
String task = (String) req.getParameter("task"); // "getRawPhoto"
String data = (String) req.getParameter("data"); // "locationPictureId"
String serviceName = (String) req.getParameter("serviceName");
if (serviceName == null)
serviceName = "track";
String taskType = (String) req.getParameter("taskType");
if (taskType == null)
taskType = "named";
// Service markup: sc=serviceCollection, s=service, p=property
content = "<sc>" + " <s>" + " <p k='serviceName'>" + serviceName + "</p>"
+ " <p k='taskType'>" + taskType + "</p>" + " <p k='task'>" + task
+ "</p>" + " <p k='data'>" + data + "</p>" + " </s>" + "</sc>";
}
MsgUnit msgUnit = new MsgUnit("<key oid='" + topicId + "'/>", content, qos);
log(getInfo(req) + "Sending request to " + topicId + ": " + content);
MsgUnit[] msgUnitArr = blasterInstance.getXmlBlasterAccess().request(msgUnit,
timeout, maxEntries);
if (msgUnitArr.length > 0) {
String contentMime = msgUnitArr[0].getQosData().getClientProperty(
"contentMime", "image/jpeg");
res.setContentType(contentMime);
log(getInfo(req) + "Returning request/reply image '" + contentMime + "' length="
+ msgUnitArr[0].getContent().length);
out = null;
ServletOutputStream binOut = res.getOutputStream();
byte[] buff = msgUnitArr[0].getContent();
binOut.write(buff, 0, buff.length);
binOut.flush();
binOut.close();
}
return;
}
/* see XbAccess.js/watchee.js for an example:
In the mode "updatePoll" this script polls every 8000 millis for update
and the servlet returns directly if nothing is available, this is suboptimal
as we have a delay of up to 8 seconds.
In the mode "updatePollBlocking" we don't poll but the servlet blocks our call
and immediately returns when update messages arrive.
To prevent from e.g. proxy timeouts the servlet returns after 15sec and we immediately
poll again.
*/
// "timeout" and "numEntries" is only evaluated for "updatePollBlocking"
boolean updatePoll = actionType.equals("updatePoll");
boolean updatePollBlocking = actionType.equals("updatePollBlocking");
if (updatePoll || updatePollBlocking) {
if (newBrowser) // The initial call should not be the AjaxPoller
throw new XmlBlasterException(Global.instance(), ErrorCode.USER_NOT_CONNECTED, "AjaxServlet", "Connection is lost, please login again");
boolean onlyContent = get(req, "onlyContent", false);
long timeout = get(req, "timeout", (updatePoll) ? 0L : 15000L);
int numEntries = get(req, "numEntries", -1);
int count = blasterInstance.sendUpdates(out, onlyContent, numEntries, timeout);
if (count == 0) { // watchee hack
if (newBrowser || forceLoad) {
String initGps = (String) req.getParameter("initGps");
if (initGps != null && "true".equalsIgnoreCase(initGps.trim())) {
String tmp = blasterInstance.getStartupPos();
if (tmp.length() > 0) {
out.write(tmp);
log(getInfo(req) + tmp);
}
}
}
} else
log(getInfo(req) + " Sending " + count + " received update messages to browser");
return;
}
if (actionType.equals("plainGet")) {
blasterInstance.plainGet(req, res, out);
}
// log(getInfo(req)+"Ignoring identical");
} catch (XmlBlasterException e) {
log("newBrowser=" + newBrowser + " forceLoad=" + forceLoad + ": "
+ e.toString());
// if (newBrowser || forceLoad)
// out.write(blasterInstance.getStartupPos());
throwable = e;
} catch (Throwable e) {
log("newBrowser=" + newBrowser + " forceLoad=" + forceLoad + ": "
+ e.toString());
e.printStackTrace();
throwable = e;
} finally {
if (out != null) {
//res.setContentType("text/xml");
//res.setCharacterEncoding("UTF-8");
res.setContentType("text/xml; charset=UTF-8");
// For HTML: out.println("<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\" />");
PrintWriter backToBrowser = res.getWriter();
if (out.getBuffer().length() > 0)
log("Sending now '" + out.getBuffer().toString() + "'");
if (out.getBuffer().length() > 0)
backToBrowser.write(out.getBuffer().toString());
else {
if (throwable != null) {
StringBuffer sb = new StringBuffer(256);
sb.append("<xmlBlasterResponse>");
XmlBlasterException ex = (XmlBlasterException)throwable;
if (throwable instanceof XmlBlasterException) {
ex = (XmlBlasterException)throwable;
if (ex.isErrorCode(ErrorCode.INTERNAL_STOP)) { // XmlScript Sax Parser stopped
Throwable th = ex.getEmbeddedException();
if (th != null && th instanceof XmlBlasterException) {
ex = (XmlBlasterException)th;
//ex.changeErrorCode(((XmlBlasterException)th).getErrorCode());
}
}
}
else {
ex = new XmlBlasterException(Global.instance(), ErrorCode.INTERNAL_UNKNOWN, "AjaxServlet", "Unknown problem", throwable);
}
sb.append(ex.toXml());
sb.append("</xmlBlasterResponse>");
if (blasterInstance != null)
blasterInstance.shutdown();
/*
<xmlBlasterResponse>