public void execute(SPFSession session, FutureSPFResult result, boolean throttle) { SPFChecker checker; while ((checker = session.popChecker()) != null) { // only execute checkers we added (better recursivity) log.debug("Executing checker: " + checker); try { DNSLookupContinuation cont = checker.checkSPF(session); // if the checker returns a continuation we return it if (cont != null) { invokeAsynchService(session, result, cont, throttle); return; } } catch (Exception e) { while (e != null) { while (checker == null || !(checker instanceof SPFCheckerExceptionCatcher)) { checker = session.popChecker(); } try { ((SPFCheckerExceptionCatcher) checker).onException(e, session); e = null; } catch (SPFResultException ex) { e = ex; } finally { checker = null; } } } } result.setSPFResult(session); }
public SPFChecker init(SPFSession spfSession) { // TODO understand what exactly we have to do now that spfData is a session // and contains much more than the input data. // do we need to create a new session at all? // do we need to backup the session attributes and restore them? this.previousResult = spfSession.getCurrentResult(); this.previousDomain = spfSession.getCurrentDomain(); this.previousResultExpanded = spfSession.getCurrentResultExpanded(); return this; }
/** @see org.apache.james.jspf.core.SPFChecker#checkSPF(org.apache.james.jspf.core.SPFSession) */ public DNSLookupContinuation checkSPF(SPFSession spfData) throws PermErrorException, TempErrorException, NoneException, NeutralException { // update currentDepth spfData.increaseCurrentDepth(); SPFChecker cleanupAndResultHandler = new CleanupAndResultChecker().init(spfData); spfData.pushChecker(cleanupAndResultHandler); spfData.pushChecker(new ExpandedChecker()); return macroExpand.checkExpand(getHost(), spfData, MacroExpand.DOMAIN); }
public void run() { while (true) { IResponse resp = responseQueue.removeResponse(); Integer respId = (Integer) resp.getId(); SPFSession session = sessions.remove(respId); FutureSPFResult result = results.remove(respId); DNSLookupContinuation cont = (DNSLookupContinuation) session.getAttribute(ATTRIBUTE_STAGED_EXECUTOR_CONTINUATION); DNSResponse response; if (resp.getException() != null) { response = new DNSResponse((TimeoutException) resp.getException()); } else { response = new DNSResponse(resp.getValue()); } try { cont = cont.getListener().onDNSResponse(response, session); if (cont != null) { invokeAsynchService(session, result, cont, false); } else { execute(session, result, false); } } catch (Exception e) { SPFChecker checker = null; while (e != null) { while (checker == null || !(checker instanceof SPFCheckerExceptionCatcher)) { checker = session.popChecker(); } try { ((SPFCheckerExceptionCatcher) checker).onException(e, session); e = null; } catch (SPFResultException ex) { e = ex; } finally { checker = null; } } execute(session, result, false); } } }
/** * @see org.apache.james.jspf.core.SPFChecker#checkSPF(org.apache.james.jspf.core.SPFSession) */ public DNSLookupContinuation checkSPF(SPFSession spfData) throws PermErrorException, TempErrorException { // throws a PermErrorException that we can pass through String host = macroExpand.expand(getHost(), spfData, MacroExpand.DOMAIN); spfData.setCurrentDomain(host); // On includes we should not use the explanation of the included domain spfData.setIgnoreExplanation(true); // set a null current result spfData.setCurrentResult(null); spfData.setCurrentResultExpanded(null); spfData.pushChecker(spfChecker); return null; }
/** * @see org.apache.james.jspf.core.SPFChecker#checkSPF(org.apache.james.jspf.core.SPFSession) */ public DNSLookupContinuation checkSPF(SPFSession spfData) throws PermErrorException, TempErrorException, NeutralException, NoneException { String currentResult = spfData.getCurrentResult(); restoreSession(spfData); if (currentResult == null) { throw new TempErrorException("included checkSPF returned null"); } else if (currentResult.equals(SPF1Constants.PASS)) { // TODO this won't work asynchronously spfData.setAttribute(Directive.ATTRIBUTE_MECHANISM_RESULT, Boolean.TRUE); } else if (currentResult.equals(SPF1Constants.FAIL) || currentResult.equals(SPF1Constants.SOFTFAIL) || currentResult.equals(SPF1Constants.NEUTRAL)) { // TODO this won't work asynchronously spfData.setAttribute(Directive.ATTRIBUTE_MECHANISM_RESULT, Boolean.FALSE); } else { throw new TempErrorException("included checkSPF returned an Illegal result"); } return null; }
/** * throttle should be true only when the caller thread is the client and not the worker thread. We * could even remove the throttle parameter and check the currentThread. This way the worker is * never "blocked" while outside callers will be blocked if our queue is too big (so this is not * fully "asynchronous"). */ private synchronized void invokeAsynchService( SPFSession session, FutureSPFResult result, DNSLookupContinuation cont, boolean throttle) { while (throttle && results.size() > 50) { try { this.wait(100); } catch (InterruptedException e) { } } int nextId = nextId(); sessions.put(new Integer(nextId), session); results.put(new Integer(nextId), result); session.setAttribute(ATTRIBUTE_STAGED_EXECUTOR_CONTINUATION, cont); dnsProbe.getRecordsAsynch(cont.getRequest(), nextId, responseQueue); }
private void restoreSession(SPFSession spfData) { spfData.setIgnoreExplanation(false); spfData.setCurrentDomain(previousDomain); spfData.setCurrentResult(previousResult); spfData.setCurrentResultExpanded(previousResultExpanded); }