use of org.directwebremoting.extend.ServerException in project ma-core-public by infiniteautomation.
the class Batch method parseParameters.
/**
* Fish out the important parameters
* @throws ServerException If the parsing of input parameter fails
*/
protected void parseParameters() throws ServerException {
Map paramMap = getAllParameters();
calls = new Calls();
// Work out how many calls are in this packet
String callStr = (String) paramMap.remove(ProtocolConstants.INBOUND_CALL_COUNT);
int callCount;
try {
callCount = Integer.parseInt(callStr);
} catch (NumberFormatException ex) {
throw new ServerException(Messages.getString("BaseCallMarshaller.BadCallCount"));
}
// Extract the ids, scriptnames and methodnames
for (int callNum = 0; callNum < callCount; callNum++) {
Call call = new Call();
calls.addCall(call);
InboundContext inctx = new InboundContext();
inboundContexts.add(inctx);
String prefix = ProtocolConstants.INBOUND_CALLNUM_PREFIX + callNum + ProtocolConstants.INBOUND_CALLNUM_SUFFIX;
// The special values
String callId = (String) paramMap.remove(prefix + ProtocolConstants.INBOUND_KEY_ID);
call.setCallId(callId);
if (!LocalUtil.isLetterOrDigitOrUnderline(callId)) {
throw new SecurityException("Call IDs may only contain Java Identifiers");
}
String scriptName = (String) paramMap.remove(prefix + ProtocolConstants.INBOUND_KEY_SCRIPTNAME);
call.setScriptName(scriptName);
if (!LocalUtil.isLetterOrDigitOrUnderline(scriptName)) {
throw new SecurityException("Script names may only contain Java Identifiers");
}
String methodName = (String) paramMap.remove(prefix + ProtocolConstants.INBOUND_KEY_METHODNAME);
call.setMethodName(methodName);
if (!LocalUtil.isLetterOrDigitOrUnderline(methodName)) {
throw new SecurityException("Method names may only contain Java Identifiers");
}
// Look for parameters to this method
for (Iterator it = paramMap.entrySet().iterator(); it.hasNext(); ) {
Map.Entry entry = (Map.Entry) it.next();
String key = (String) entry.getKey();
if (key.startsWith(prefix)) {
String data = (String) entry.getValue();
String[] split = ParseUtil.splitInbound(data);
String value = split[LocalUtil.INBOUND_INDEX_VALUE];
String type = split[LocalUtil.INBOUND_INDEX_TYPE];
inctx.createInboundVariable(callNum, key, type, value);
it.remove();
}
}
}
String batchId = (String) paramMap.remove(ProtocolConstants.INBOUND_KEY_BATCHID);
calls.setBatchId(batchId);
if (!LocalUtil.isLetterOrDigitOrUnderline(batchId)) {
throw new SecurityException("Batch IDs may only contain Java Identifiers");
}
httpSessionId = (String) paramMap.remove(ProtocolConstants.INBOUND_KEY_HTTP_SESSIONID);
scriptSessionId = (String) paramMap.remove(ProtocolConstants.INBOUND_KEY_SCRIPT_SESSIONID);
page = (String) paramMap.remove(ProtocolConstants.INBOUND_KEY_PAGE);
for (Iterator it = paramMap.entrySet().iterator(); it.hasNext(); ) {
Map.Entry entry = (Map.Entry) it.next();
String key = (String) entry.getKey();
String value = (String) entry.getValue();
if (key.startsWith(ProtocolConstants.INBOUND_KEY_METADATA)) {
spareParameters.put(key.substring(ProtocolConstants.INBOUND_KEY_METADATA.length()), value);
}
}
}
use of org.directwebremoting.extend.ServerException in project ma-core-public by infiniteautomation.
the class ParseUtil method parsePost.
/**
* Parse an HTTP POST request to fill out the scriptName, methodName and
* paramList properties. This method should not fail unless it will not
* be possible to return any sort of error to the user. Failure cases should
* be handled by the <code>checkParams()</code> method.
* @param req The original browser's request
* @return The equivalent of HttpServletRequest.getParameterMap() for now
* @throws ServerException If reading from the request body stream fails
*/
public static Map parsePost(HttpServletRequest req) throws ServerException {
Map paramMap = new HashMap();
BufferedReader in = null;
try {
// I've had reports of data loss in Tomcat 5.0 that relate to this bug
// http://issues.apache.org/bugzilla/show_bug.cgi?id=27447
// See mails to users@dwr.dev.java.net:
// Subject: "Tomcat 5.x read-ahead problem"
// From: CAKALIC, JAMES P [AG-Contractor/1000]
// It would be more normal to do the following:
// BufferedReader in = req.getReader();
in = new BufferedReader(new InputStreamReader(req.getInputStream()));
while (true) {
String line = in.readLine();
if (line == null) {
if (paramMap.isEmpty()) {
// Normally speaking we should just bail out, but if
// we are using DWR with Acegi without ActiveX on IE,
// then Acegi 'fixes' the parameters for us.
Enumeration en = req.getParameterNames();
while (en.hasMoreElements()) {
String name = (String) en.nextElement();
paramMap.put(name, req.getParameter(name));
}
}
break;
}
if (line.indexOf('&') != -1) {
// If there are any &s then this must be iframe post and all the
// parameters have got dumped on one line, split with &
log.debug("Using iframe POST mode");
StringTokenizer st = new StringTokenizer(line, "&");
while (st.hasMoreTokens()) {
String part = st.nextToken();
part = LocalUtil.decode(part);
parsePostLine(part, paramMap);
}
} else {
// Horay, this is a normal one!
parsePostLine(line, paramMap);
}
}
} catch (Exception ex) {
throw new ServerException(Messages.getString("ParseUtil.InputReadFailed"), ex);
} finally {
if (in != null) {
try {
in.close();
} catch (IOException ex) {
// Ignore
}
}
}
// http://developer.apple.com/internet/safari/uamatrix.html
if (paramMap.size() == 1) {
// This looks like a broken Mac where the line endings are confused
log.debug("Using Broken Safari POST mode");
// Iterators insist that we call hasNext() before we start
Iterator it = paramMap.keySet().iterator();
if (!it.hasNext()) {
throw new IllegalStateException("No entries in non empty map!");
}
// So get the first
String key = (String) it.next();
String value = (String) paramMap.get(key);
String line = key + ProtocolConstants.INBOUND_DECL_SEPARATOR + value;
StringTokenizer st = new StringTokenizer(line, "\n");
while (st.hasMoreTokens()) {
String part = st.nextToken();
part = LocalUtil.decode(part);
parsePostLine(part, paramMap);
}
}
return paramMap;
}
use of org.directwebremoting.extend.ServerException in project ma-core-public by infiniteautomation.
the class ParseUtil method parseGet.
/**
* Parse an HTTP GET request to fill out the scriptName, methodName and
* paramList properties. This method should not fail unless it will not
* be possible to return any sort of error to the user. Failure cases should
* be handled by the <code>checkParams()</code> method.
* @param req The original browser's request
* @return Simply HttpRequest.getParameterMap() for now
* @throws ServerException If the parsing fails
*/
public static Map parseGet(HttpServletRequest req) throws ServerException {
Map convertedMap = new HashMap();
Map paramMap = req.getParameterMap();
for (Iterator it = paramMap.entrySet().iterator(); it.hasNext(); ) {
Map.Entry entry = (Map.Entry) it.next();
String key = (String) entry.getKey();
String[] array = (String[]) entry.getValue();
if (array.length == 1) {
convertedMap.put(key, array[0]);
} else {
throw new ServerException(Messages.getString("ParseUtil.MultiValues", key));
}
}
return convertedMap;
}
use of org.directwebremoting.extend.ServerException in project ma-core-public by infiniteautomation.
the class PollHandler method handle.
/* (non-Javadoc)
* @see org.directwebremoting.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
public void handle(HttpServletRequest request, HttpServletResponse response) throws IOException {
// all Jetty continuation restarts.
if (JettyContinuationSleeper.isRestart(request)) {
JettyContinuationSleeper.restart(request);
return;
}
// A PollBatch is the information that we expect from the request.
// if the parse fails we can do little more than tell the browser that
// something went wrong.
final PollBatch batch;
try {
batch = new PollBatch(request, pageNormalizer);
} catch (ServerException ex) {
// Send a batch exception to the server because the parse failed
String script = EnginePrivate.getRemoteHandleBatchExceptionScript(null, ex);
sendErrorScript(response, script);
return;
}
String bodySessionId = batch.getHttpSessionId();
if (crossDomainSessionSecurity) {
checkNotCsrfAttack(request, bodySessionId);
}
// We might need to complain that reverse ajax is not enabled.
if (!activeReverseAjaxEnabled) {
log.error("Polling and Comet are disabled. To enable them set the init-param activeReverseAjaxEnabled to true. See http://getahead.org/dwr/server/servlet for more.");
String script = EnginePrivate.getRemotePollCometDisabledScript(batch.getBatchId());
sendErrorScript(response, script);
return;
}
// Complain if GET is disallowed
if (batch.isGet() && !allowGetForSafariButMakeForgeryEasier) {
// Send a batch exception to the server because the parse failed
String script = EnginePrivate.getRemoteHandleBatchExceptionScript(batch.getBatchId(), new SecurityException("GET Disallowed"));
sendErrorScript(response, script);
return;
}
// A script conduit is some route from a ScriptSession back to the page
// that belongs to the session. There may be zero or many of these
// conduits (although if there are more than 2, something is strange)
// All scripts destined for a page go to a ScriptSession and then out
// via a ScriptConduit.
final RealScriptSession scriptSession = batch.getScriptSession();
// Create a conduit depending on the type of request (from the URL)
final BaseScriptConduit conduit = createScriptConduit(batch, response);
// So we're going to go to sleep. How do we wake up?
final Sleeper sleeper;
// If this is Jetty then we can use Continuations
if (Continuation.isJetty()) {
sleeper = new JettyContinuationSleeper(request);
} else {
sleeper = new ThreadWaitSleeper();
}
// There are various reasons why we want to wake up and carry on ...
final List alarms = new ArrayList();
// If the conduit has an error flushing data, it needs to give up
alarms.add(conduit.getErrorAlarm());
// Set the system up to resume on output (perhaps with delay)
if (batch.getPartialResponse() == PartialResponse.NO || maxWaitAfterWrite != -1) {
// add an output listener to the script session that calls the
// "wake me" method on whatever is putting us to sleep
alarms.add(new OutputAlarm(scriptSession, maxWaitAfterWrite));
}
// Set the system up to resume anyway after maxConnectedTime
long connectedTime = serverLoadMonitor.getConnectedTime();
alarms.add(new TimedAlarm(connectedTime));
// We also need to wake-up if the server is being shut down
// WARNING: This code has a non-obvious side effect - The server load
// monitor (which hands out shutdown messages) also monitors usage by
// looking at the number of connected alarms.
alarms.add(new ShutdownAlarm(serverLoadMonitor));
// Make sure that all the alarms know what to wake
for (Iterator it = alarms.iterator(); it.hasNext(); ) {
Alarm alarm = (Alarm) it.next();
alarm.setAlarmAction(sleeper);
}
// Register the conduit with a script session so messages can get out.
// This must happen late on in this method because this will cause any
// scripts cached in the script session (because there was no conduit
// available when they were written) to be sent to the conduit.
// We need any AlarmScriptConduits to be notified so they can make
// maxWaitWfterWrite work for all cases
scriptSession.addScriptConduit(conduit);
// We need to do something sensible when we wake up ...
Runnable onAwakening = new Runnable() {
public void run() {
// Cancel all the alarms
for (Iterator it = alarms.iterator(); it.hasNext(); ) {
Alarm alarm = (Alarm) it.next();
alarm.cancel();
}
// We can't be used as a conduit to the browser any more
scriptSession.removeScriptConduit(conduit);
// Tell the browser to come back at the right time
try {
int timeToNextPoll = serverLoadMonitor.getDisconnectedTime();
conduit.close(timeToNextPoll);
} catch (IOException ex) {
log.warn("Failed to write reconnect info to browser");
}
}
};
// Actually go to sleep. This *must* be the last thing in this method to
// cope with all the methods of affecting Threads. Jetty throws,
// Weblogic continues, others wait().
sleeper.goToSleep(onAwakening);
}
Aggregations