Class BotClassifier

java.lang.Object
org.frontcache.bots.BotClassifier

public class BotClassifier extends Object
Decides a request's client type - bot or guest - from conf/bots.conf. Evaluation order, first match wins:
  1. built-in no-user-agent (a request with no User-Agent is a bot);
  2. rules from conf/bots.conf, in file order;
  3. bare User-Agent keywords from the same file, in file order - so an explicit rule always wins over a keyword, whichever way round the file is written;
  4. built-in default (guest), which always matches.
The verdict is a behaviour profile, not a judgement. It selects which branch of a cached WebResponse's expireTimeMap applies - a different TTL, or cache vs. an origin call - and whether an <fc:include client="..."> fragment is resolved. Guard rules read it back through client-type:, but that is one consumer among several. This is a process-wide singleton rather than a member of FrontCacheEngine, for the same reason ClientIpResolver is: the management API and FCConfig both need to read it, and neither may boot an engine by asking. Runs on the request thread for every request, so classify() allocates nothing on the common path and never throws: a predicate that blows up is logged once and treated as "did not match", which degrades to the client type the next rule decides rather than to a 500.
  • Field Details

  • Method Details

    • getInstance

      public static BotClassifier getInstance()
      Returns:
      the classifier built from the current configuration, created on first use
    • reload

      public static void reload()
      Re-reads conf/bots.conf. Called by the reload-bots management action, and by the engine's reload - adding a crawler to the list used to mean restarting the node. Hit counters start from zero again, because the rules they belong to are new objects.
    • install

      public static void install(BotClassifier classifier)
      for tests - installs a classifier without going through FCConfig
    • of

      public static BotClassifier of(List<BotRule> rules)
      for tests - builds a classifier over an explicit rule list
    • getRules

      public List<BotRule> getRules()
      The rules this node is running, in evaluation order, each carrying its hit count. Rendered by the console's Bot Rules screen.
    • getKeywords

      public Set<String> getKeywords()
      Bare User-Agent keywords from the file, in file order. Reported separately from the rules because a console older than 2.9.0 knows only this shape.
    • classify

      public BotRule classify(RequestContext context)
      Classifies one request. Never throws. Only the DECIDING rule counts a hit - a rule below it is never evaluated - so the console's Hits column reads as "share of traffic decided here", and a rule shadowed by a broader one above it sits at zero, which is the most useful thing that column says. A dry-run rule counts and evaluation continues past it: measuring a rule before it acts is the whole point of dry-run.
      Parameters:
      context - current request; may carry a null or recycled servlet request
      Returns:
      the rule that decided, never null - ask it for BotRule.getClientType()
    • validate

      public static List<String> validate(String content)
      Dry-parses a candidate bots.conf without touching anything live, for the set-config management action. The line-kind decision is the same one readConfigFile(List, List, Set, boolean) makes - a line with no | outside a group is a bare keyword, anything else is a rule - because a validator that classified lines differently from the loader would pass files the loader then refuses, which is worse than no validator.
      Returns:
      one message per unusable line, "line N: ...", in file order; empty when the whole file parses