Пример #1
0
 /* ------------------------------------------------------------ */
 @Override
 public void resume() {
   AsyncContext context = _context;
   if (context == null) throw new IllegalStateException();
   _resumed = true;
   _context.dispatch();
 }
Пример #2
0
    @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();
    }
Пример #3
0
 @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();
 }
Пример #4
0
 @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();
   }
 }
Пример #5
0
  /*
   * (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");
  }
Пример #6
0
  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\"}");
  }
Пример #7
0
  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();
      }
    }
  }
Пример #8
0
  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();
        }
      }
    }
  }