/* ------------------------------------------------------------ */ @Override public void resume() { AsyncContext context = _context; if (context == null) throw new IllegalStateException(); _resumed = true; _context.dispatch(); }
@Override public void onEvent(byte[] data, long seq, boolean endOfBatch) throws Exception { crc32.update(data); long crc = crc32.getValue(); byte[] md5 = md5Digest.digest(data); byte[] sha1 = sha1Digest.digest(data); Data d = new Data(String.valueOf(crc), toHex(md5), toHex(sha1)); int size = contexts.size(); for (int i = 0; i < size; i++) { AsyncContext context = contexts.poll(); if (null != context) { context.getRequest().setAttribute("data", d); try { context.dispatch(); } catch (Exception e) { } } else { break; } } crc32.reset(); md5Digest.reset(); sha1Digest.reset(); }
@Override public void onTimeout(AsyncEvent event) throws IOException { // Remove before it's redispatched, so it won't be // redispatched again at the end of the filtering. AsyncContext asyncContext = event.getAsyncContext(); _queues[priority].remove(asyncContext); asyncContext.dispatch(); }
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // Only set the status on the first call (the dispatch will trigger // another call to this Servlet) if (resp.getStatus() != HttpServletResponse.SC_BAD_REQUEST) { resp.setStatus(HttpServletResponse.SC_BAD_REQUEST); AsyncContext ac = req.startAsync(); ac.dispatch(); } }
/* * (non-Javadoc) * * @see java.lang.Runnable#run() */ @Override public void run() { try { if (timerValue > 0) { // Simulate long running operation Timer.startNew(timerValue); } } catch (InterruptedException e) { throw new IllegalStateException("Interrupted"); } // Dispatch or complete if (useDispatch) { if (dispatchPath != null) { actx.dispatch(dispatchPath); } else { actx.dispatch(); } } else { actx.complete(); } logger.log("Async processing finished"); }
private synchronized void chat( HttpServletRequest request, HttpServletResponse response, String username, String message) throws IOException { Map<String, Member> room = _rooms.get(request.getPathInfo()); if (room != null) { // Post chat to all members for (Member m : room.values()) { synchronized (m) { m._queue.add(username); // from m._queue.add(message); // chat // wakeup member if polling AsyncContext async = m._async.get(); if (async != null & m._async.compareAndSet(async, null)) async.dispatch(); } } } response.setContentType("text/json;charset=utf-8"); PrintWriter out = response.getWriter(); out.print("{action:\"chat\"}"); }
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { boolean accepted = false; try { Boolean suspended = (Boolean) request.getAttribute(_suspended); if (suspended == null) { accepted = _passes.tryAcquire(getWaitMs(), TimeUnit.MILLISECONDS); if (accepted) { request.setAttribute(_suspended, Boolean.FALSE); if (LOG.isDebugEnabled()) LOG.debug("Accepted {}", request); } else { request.setAttribute(_suspended, Boolean.TRUE); int priority = getPriority(request); AsyncContext asyncContext = request.startAsync(); long suspendMs = getSuspendMs(); if (suspendMs > 0) asyncContext.setTimeout(suspendMs); asyncContext.addListener(_listeners[priority]); _queues[priority].add(asyncContext); if (LOG.isDebugEnabled()) LOG.debug("Suspended {}", request); return; } } else { if (suspended) { request.setAttribute(_suspended, Boolean.FALSE); Boolean resumed = (Boolean) request.getAttribute(_resumed); if (resumed == Boolean.TRUE) { _passes.acquire(); accepted = true; if (LOG.isDebugEnabled()) LOG.debug("Resumed {}", request); } else { // Timeout! try 1 more time. accepted = _passes.tryAcquire(getWaitMs(), TimeUnit.MILLISECONDS); if (LOG.isDebugEnabled()) LOG.debug("Timeout {}", request); } } else { // Pass through resume of previously accepted request. _passes.acquire(); accepted = true; if (LOG.isDebugEnabled()) LOG.debug("Passthrough {}", request); } } if (accepted) { chain.doFilter(request, response); } else { if (LOG.isDebugEnabled()) LOG.debug("Rejected {}", request); ((HttpServletResponse) response).sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE); } } catch (InterruptedException e) { ((HttpServletResponse) response).sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE); } finally { if (accepted) { for (int p = _queues.length - 1; p >= 0; --p) { AsyncContext asyncContext = _queues[p].poll(); if (asyncContext != null) { ServletRequest candidate = asyncContext.getRequest(); Boolean suspended = (Boolean) candidate.getAttribute(_suspended); if (suspended == Boolean.TRUE) { candidate.setAttribute(_resumed, Boolean.TRUE); asyncContext.dispatch(); break; } } } _passes.release(); } } }
protected void doFilter( HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException { if (!isEnabled()) { filterChain.doFilter(request, response); return; } // Look for the rate tracker for this request. RateTracker tracker = (RateTracker) request.getAttribute(__TRACKER); if (tracker == null) { // This is the first time we have seen this request. if (LOG.isDebugEnabled()) LOG.debug("Filtering {}", request); // Get a rate tracker associated with this request, and record one hit. tracker = getRateTracker(request); // Calculate the rate and check it is over the allowed limit final boolean overRateLimit = tracker.isRateExceeded(System.currentTimeMillis()); // Pass it through if we are not currently over the rate limit. if (!overRateLimit) { if (LOG.isDebugEnabled()) LOG.debug("Allowing {}", request); doFilterChain(filterChain, request, response); return; } // We are over the limit. // So either reject it, delay it or throttle it. long delayMs = getDelayMs(); boolean insertHeaders = isInsertHeaders(); switch ((int) delayMs) { case -1: { // Reject this request. LOG.warn( "DOS ALERT: Request rejected ip={}, session={}, user={}", request.getRemoteAddr(), request.getRequestedSessionId(), request.getUserPrincipal()); if (insertHeaders) response.addHeader("DoSFilter", "unavailable"); response.sendError(getTooManyCode()); return; } case 0: { // Fall through to throttle the request. LOG.warn( "DOS ALERT: Request throttled ip={}, session={}, user={}", request.getRemoteAddr(), request.getRequestedSessionId(), request.getUserPrincipal()); request.setAttribute(__TRACKER, tracker); break; } default: { // Insert a delay before throttling the request, // using the suspend+timeout mechanism of AsyncContext. LOG.warn( "DOS ALERT: Request delayed={}ms, ip={}, session={}, user={}", delayMs, request.getRemoteAddr(), request.getRequestedSessionId(), request.getUserPrincipal()); if (insertHeaders) response.addHeader("DoSFilter", "delayed"); request.setAttribute(__TRACKER, tracker); AsyncContext asyncContext = request.startAsync(); if (delayMs > 0) asyncContext.setTimeout(delayMs); asyncContext.addListener(new DoSTimeoutAsyncListener()); return; } } } if (LOG.isDebugEnabled()) LOG.debug("Throttling {}", request); // Throttle the request. boolean accepted = false; try { // Check if we can afford to accept another request at this time. accepted = _passes.tryAcquire(getMaxWaitMs(), TimeUnit.MILLISECONDS); if (!accepted) { // We were not accepted, so either we suspend to wait, // or if we were woken up we insist or we fail. Boolean throttled = (Boolean) request.getAttribute(__THROTTLED); long throttleMs = getThrottleMs(); if (throttled != Boolean.TRUE && throttleMs > 0) { int priority = getPriority(request, tracker); request.setAttribute(__THROTTLED, Boolean.TRUE); if (isInsertHeaders()) response.addHeader("DoSFilter", "throttled"); AsyncContext asyncContext = request.startAsync(); request.setAttribute(_suspended, Boolean.TRUE); if (throttleMs > 0) asyncContext.setTimeout(throttleMs); asyncContext.addListener(_listeners[priority]); _queues[priority].add(asyncContext); if (LOG.isDebugEnabled()) LOG.debug("Throttled {}, {}ms", request, throttleMs); return; } Boolean resumed = (Boolean) request.getAttribute(_resumed); if (resumed == Boolean.TRUE) { // We were resumed, we wait for the next pass. _passes.acquire(); accepted = true; } } // If we were accepted (either immediately or after throttle)... if (accepted) { // ...call the chain. if (LOG.isDebugEnabled()) LOG.debug("Allowing {}", request); doFilterChain(filterChain, request, response); } else { // ...otherwise fail the request. if (LOG.isDebugEnabled()) LOG.debug("Rejecting {}", request); if (isInsertHeaders()) response.addHeader("DoSFilter", "unavailable"); response.sendError(getTooManyCode()); } } catch (InterruptedException e) { LOG.ignore(e); response.sendError(getTooManyCode()); } finally { if (accepted) { try { // Wake up the next highest priority request. for (int p = _queues.length - 1; p >= 0; --p) { AsyncContext asyncContext = _queues[p].poll(); if (asyncContext != null) { ServletRequest candidate = asyncContext.getRequest(); Boolean suspended = (Boolean) candidate.getAttribute(_suspended); if (suspended == Boolean.TRUE) { if (LOG.isDebugEnabled()) LOG.debug("Resuming {}", request); candidate.setAttribute(_resumed, Boolean.TRUE); asyncContext.dispatch(); break; } } } } finally { _passes.release(); } } } }