public void service(ServletRequest request, ServletResponse response)
      throws ServletException, IOException {

    // Get print writer.
    PrintWriter pw = response.getWriter();

    // Get enumeration of parameter names.
    Enumeration e = request.getParameterNames();

    // Display parameter names and values.
    while (e.hasMoreElements()) {
      String pname = (String) e.nextElement();
      pw.print(pname + " = ");
      String pvalue = request.getParameter(pname);
      pw.println(pvalue);
    }
    pw.close();
  }
Ejemplo n.º 2
0
  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      throws IOException, ServletException {
    String longAddr = null, shortAddr, s, transactionKey = null;
    int count;
    boolean ignorable = false;

    synchronized (simultaneousRequestsByShortIPAddr) {
      if (totalSimultaneousRequests >= maxTotalSimultaneousRequests) {
        log.error(
            "This system has exceeded the maxTotalSimultaneousRequests limit of "
                + maxTotalSimultaneousRequests);
        log.error(simultaneousRequestsByShortIPAddr);
        for (String str : simultaneousRequests) log.error(str);
        ((HttpServletResponse) response).setStatus(HttpURLConnection.HTTP_UNAVAILABLE);
        response.setContentType("text/html");
        PrintWriter writer = response.getWriter();
        writer.println("<html><body><h1>Service Temporarily Unavailable</h1>");
        writer.println(
            "The system is experiencing a severe load and is temporarily unable to accept new requests");
        if (contactInfo != null)
          writer.println("<p>Contact " + contactInfo + " for more information</p>");
        writer.println("</body></html>");
        writer.close();
        return;
      }
      if (addressInHeader != null) {
        @SuppressWarnings("unchecked")
        Enumeration<String> addrs = ((HttpServletRequest) request).getHeaders(addressInHeader);
        while (addrs.hasMoreElements()) {
          longAddr = addrs.nextElement();
          if (longAddr == null) {
            if (++addressInHeaderErrorCount < 10)
              log.error("Expected a " + addressInHeader + " header but got null");
            continue;
          }
          if (longAddr.lastIndexOf('.') >= 0) break;
        }
      }
      if (longAddr == null) longAddr = request.getRemoteAddr();
      int i = longAddr.lastIndexOf('.');
      if (i < 0) {
        log.error("bogus IP address: '" + longAddr + "'");
        longAddr = "0.0.0.0";
      }
      shortAddr = longAddr.substring(0, i); // trim off 4th number group
      // that lets us spot requests from clusters
      s = equivalentAddresses.get(shortAddr); // map one short addr to another?
      if (s != null) shortAddr = s;
      if (ignorableAddresses.contains(shortAddr)) {
        ignorable = true;
      } else {
        Integer icount = simultaneousRequestsByShortIPAddr.get(shortAddr);
        if (icount != null) count = icount;
        else count = 0;

        int maxSimultaneousRequests =
            (maxTotalSimultaneousRequests - totalSimultaneousRequests) / 4;
        if (maxSimultaneousRequests == 0) maxSimultaneousRequests = 1;
        if (count >= maxSimultaneousRequests) {
          log.error(
              "IP addr "
                  + shortAddr
                  + ".* has exceeded "
                  + maxSimultaneousRequests
                  + " simultaneous requests!");
          log.error("maxTotalSimultaneousRequests=" + maxTotalSimultaneousRequests);
          log.error("totalSimultaneousRequests=" + totalSimultaneousRequests);
          for (String str : simultaneousRequests) log.error(str);
          //
          // ((HttpServletResponse)response).setStatus(HttpURLConnection.HTTP_TOO_MANY_REQUESTS); //
          // someday
          ((HttpServletResponse) response).setStatus(429); // too many requests
          response.setContentType("text/html");
          PrintWriter writer = response.getWriter();
          writer.println(
              "<html><head><title>Too Many Requests</title></head><body><h1>Too Many Requests</h1>");
          writer.println(
              "You have exceeded the maximum simultaneous request value of "
                  + maxSimultaneousRequests);
          writer.println("<p>This message and your IP address have been logged and reported</p>");
          if (contactInfo != null)
            writer.println("<p>Contact " + contactInfo + " for more information</p>");
          writer.println("</body></html>");
          writer.close();
          return;
        }
        simultaneousRequestsByShortIPAddr.put(shortAddr, count + 1);
        icount = totalRequests.get(shortAddr);
        if (icount != null) count = icount;
        else count = 0;
        totalRequests.put(shortAddr, count + 1);
        totalSimultaneousRequests++;
        transactionKey =
            new StringBuilder((new Date(System.currentTimeMillis())).toString())
                .append('|')
                .append(shortAddr)
                .append('|')
                .append(((HttpServletRequest) request).getQueryString())
                .toString();
        simultaneousRequests.add(transactionKey);
      }
    }

    try {
      HttpServletResponseWrapper wrapper =
          new HttpServletResponseWrapper((HttpServletResponse) response);
      chain.doFilter(request, wrapper);
    } finally {
      if (!ignorable)
        synchronized (simultaneousRequestsByShortIPAddr) {
          totalSimultaneousRequests--;
          simultaneousRequests.remove(transactionKey);
          count = simultaneousRequestsByShortIPAddr.get(shortAddr);
          if (count == 1) // prune them from the table
          simultaneousRequestsByShortIPAddr.remove(shortAddr);
          else simultaneousRequestsByShortIPAddr.put(shortAddr, count - 1);
        }
    }

    Calendar c = new GregorianCalendar();
    int hour = c.get(Calendar.HOUR_OF_DAY);
    if (hour == 0 && nextReportingHour == 24) { // new day!
      // you could reset your daily limits table here
      nextReportingHour = 0;
    }

    if (hour >= nextReportingHour) { // generate the hourly report
      // you could reset your hourly limits table here
      nextReportingHour = hour + 1;

      if (log.isInfoEnabled()) {
        HashMap<String, Integer> map = new LinkedHashMap<String, Integer>();
        List<String> yourMapKeys = new ArrayList<String>(totalRequests.keySet());
        List<Integer> yourMapValues = new ArrayList<Integer>(totalRequests.values());
        TreeSet<Integer> sortedSet = new TreeSet<Integer>(yourMapValues);
        Integer[] sortedArray = sortedSet.descendingSet().toArray(new Integer[0]);
        int size = sortedArray.length;

        for (int i = 0; i < size; i++)
          map.put(yourMapKeys.get(yourMapValues.indexOf(sortedArray[i])), sortedArray[i]);
        Iterator<String> it = map.keySet().iterator();
        String key;
        StringBuilder sb = new StringBuilder("Top 10 users in the last hour");
        for (int i = 0; i < 10 && it.hasNext(); i++) {
          key = it.next();
          sb.append("\n    ").append(key).append(" : ").append(map.get(key));
        }
        log.info(sb);
      }
      totalRequests.clear();
    }
  }