Class WebEngineClassifier

java.lang.Object
com.iizix.server.webengine.WebEngineClassifier

public final class WebEngineClassifier extends Object
Classifies the web engine of a client as PATCHED, BEHIND, ENDED or NOT_ASSESSED from its user agent and, in iiziRun, the device's own OS version (design CC-DESIGN-WEBVIEW-WARNING sections 4 and 6, work order CC-WEBENGINE-CLASSIFIER).

Pure. No session, no EnvProps, no clock and no settings: the caller passes the four client values, the table, today and the grace period. The raw user agent comes from DeviceMatch.getUserAgent(env) at the call site. The work is two or three regular expressions over at most 1024 characters and a few map lookups, so it is safe on a Jetty I/O thread.

Fail-open. Anything that does not parse is NOT_ASSESSED, and an engine newer than the table knows is PATCHED. The verdict drives no access decision (design D-16): a spoofed user agent can only make a device look patched or unpatched to itself.

Where each version comes from (section 4.1):

  • iiziRun on Android: the engine from the user agent's Chrome/<M> token, the OS from izr.osversion, which wins over the user agent whenever izr.cordova is present.
  • Chrome on Android: the engine from the user agent; the OS from the user agent only when it is not Chrome's reduced Android 10; K, which every Chrome says whatever the real version. Other Chromium Browsers (Samsung Internet, Opera, Edge, ...) version their own patches and are NOT_ASSESSED.
  • iOS and iPadOS: the engine is the OS. iiziRun gives izr.osversion; a Browser gives OS <a>_<b>, overridden by Version/<n> when n is 26 or more, because the OS token is frozen from iOS 26 on (18_6, 18_7). An iPad in desktop mode says Macintosh; it is iOS only when izr.platform says so.
  • Anything else, desktop Browsers included: NOT_ASSESSED (design D-1).

The classification (section 6.1, today in UTC, the grace period in days):

  • Android with a known OS that the table lists as ended, on an engine no newer than that OS's last: ENDED since the day that engine stopped being patched. A known OS older than every ended entry: ENDED, day unknown.
  • Android otherwise: the next major the table knows above the engine's (Chrome 82 was never shipped, and the table may have gaps). None: PATCHED. Its first-stable day more than the grace period ago: BEHIND since that day. Else PATCHED. An engine older than the whole table is BEHIND, day unknown. A BEHIND Chrome whose OS is hidden and whose engine is the last one of an ended Android version is marked WebEngineStatus.possiblyEnded() (section 6.2).
  • iOS: an ended major is BEHIND since its end day (every device can upgrade), with the upgrade target; a major newer than the table, or between two it knows, is PATCHED; one older than the whole table is ENDED, day unknown (below iiziRun's floor, Browser only).
Author:
Christopher Mindus
  • Field Details

    • DEFAULT_GRACE_DAYS

      public static final int DEFAULT_GRACE_DAYS
      The default grace period in days (design D-3): BEHIND only when the next major has been served for longer than this.
      See Also:
    • MAX_USER_AGENT_LENGTH

      public static final int MAX_USER_AGENT_LENGTH
      A user agent longer than this is truncated before matching, as BrowserGate does.
      See Also:
    • PRODUCT_WEBVIEW

      public static final String PRODUCT_WEBVIEW
      The product name of the Android WebView.
      See Also:
    • PRODUCT_CHROME

      public static final String PRODUCT_CHROME
      The product name of Chrome.
      See Also:
    • PRODUCT_IOS

      public static final String PRODUCT_IOS
      The product name of the iOS engine.
      See Also:
  • Method Details

    • classify

      public static WebEngineStatus classify(WebEngineClassifier.Client client, WebEngineSupportTable table, LocalDate today, int graceDays)
      Classifies a client's web engine.
      Parameters:
      client - The client values.
      table - The support table.
      today - Today, UTC.
      graceDays - The grace period in days; a negative value counts as 0.
      Returns:
      The verdict, never null.