java.lang.Object
net.i2p.router.web.FormHandler
Direct Known Subclasses:
ConfigAdvancedHandler, ConfigBanHandler, ConfigClientsHandler, ConfigFamilyHandler, ConfigHomeHandler, ConfigKeyringHandler, ConfigLoggingHandler, ConfigNetHandler, ConfigPeerHandler, ConfigReseedHandler, ConfigServiceHandler, ConfigSidebarHandler, ConfigStatsHandler, ConfigTunnelsHandler, ConfigUIHandler, ConfigUpdateHandler, EventLogHelper, GraphHelper, NetDbHelper, TuningFormHandler, WizardHandler

public abstract class FormHandlerextends Object
Simple form handler base class - does not depend on servlets or jsp, but instead the subclasses are populated with javabean properties. e.g. <jsp:setProperty name="handler" property="*" />

The form is "processed" after the properties are set and the first output property is retrieved - either getAll(), getNotices() or getErrors().

This Handler will only process a single POST. The jsp bean must be declared scope=request.

  • Field Details

    • _context

      protected RouterContext _context
      Router context.
    • _log

      protected Log _log
      Class logger.
    • _settings

      protected Map _settings
      Not for multipart/form-data, will be null.
    • _requestWrapper

      protected RequestWrapper _requestWrapper
      Only for multipart/form-data. Warning, parameters are NOT XSS filtered.
    • _nonce

      private String _nonce
      The form nonce to check.
    • _action

      protected String _action
      Form action.
    • _method

      protected String _method
      Request method.
    • _errors

      private final List<FormHandler.Message> _errors
      The error messages to display.
    • _notices

      private final List<FormHandler.Message> _notices
      The notice messages to display.
    • _processed

      private boolean _processed
      True once the form was processed.
    • _valid

      private boolean _valid
      True when the form input was valid.
    • _out

      protected Writer _out
      Output writer.
    • _session

      protected HttpSession _session
      HTTP session for nonce validation.
    • RATE_LIMIT_WINDOW_MS

      static final int RATE_LIMIT_WINDOW_MS
      Length of one rate-limit window, in ms.

      The rate limiter for form submissions - it exists to slow down brute-force nonce guessing on a failed submission. One budget per key; see validate() for what the key is.

      See Also:
    • RATE_LIMIT_MAX_POSTS

      static final int RATE_LIMIT_MAX_POSTS
      POSTs admitted per window per key before further ones are refused.
      See Also:
    • RATE_LIMIT_GLOBAL_KEY

      static final String RATE_LIMIT_GLOBAL_KEY
      The single budget key the console charges POSTs to.
      See Also:
    • RATE_LIMIT_SWEEP_SIZE

      private static final int RATE_LIMIT_SWEEP_SIZE
      Above this many budgets, drop the idle ones before adding another.
      See Also:
    • RATE_LIMIT_MAP

      static final ConcurrentHashMap<String, FormHandler.RateLimitEntry> RATE_LIMIT_MAP
      Live budgets, keyed by the value passed to checkRateLimit().
  • Constructor Details

    • FormHandler

      public FormHandler()
      Starts a valid handler with no errors or notices.
  • Method Details

    • checkRateLimit

      static boolean checkRateLimit(String key, long now)
      Check and record one form submission against the budget for key.

      Package-visible, and takes the clock as an argument, so a test can walk a whole window and its rollover without sleeping.

      Parameters:
      key - the budget to charge
      now - current time in ms
      Returns:
      true if the submission is allowed; a null or empty key is allowed unconditionally, because there is nothing to charge it against
    • cleanupRateLimits

      static void cleanupRateLimits(long now)
      Remove budgets that have seen no POST for two full windows.

      Driven from the map's own size rather than a thread started in a static initializer: with one budget there is nothing to reclaim, and a thread that outlives every request and never stops is not a price worth paying for it.

      Parameters:
      now - current time in ms
    • storeSession

      public void storeSession(HttpSession session)
      For nonce validation.
      Parameters:
      session - the HTTP session
    • setContextId

      public void setContextId(String contextId)
      Configure this bean to query a particular router context.
      Parameters:
      contextId - beginning few characters of the routerHash, or null to pick the first one we come across.
    • setNonce

      public void setNonce(String val)
      Nonce value.
      Parameters:
      val - the nonce value
    • setAction

      public void setAction(String val)
      Action value.
      Parameters:
      val - the action value
    • setSettings

      public void setSettings(Map settings)
      For many forms, it's easiest just to put all the parameters here.
      Parameters:
      settings - the form parameters
    • setRequestWrapper

      public void setRequestWrapper(RequestWrapper rw)
      Only set by formhandler.jsi for multipart/form-data.
      Parameters:
      rw - the request wrapper
    • isAdvanced

      public boolean isAdvanced()
      Same as HelperBase.
      Returns:
      true if advanced mode
    • getJettyString

      protected String getJettyString(String key)
      setSettings(Map) must have been called previously Curses Jetty for returning arrays. For nofilter_ prefixed params, validates for XSS patterns.
      Parameters:
      key - the setting key
      Returns:
      trimmed string or null
    • resolveEffectiveAction

      public static String resolveEffectiveAction(String action, Map<?,?> settings)
      Resolve which operation the user actually requested.

      Forms commonly carry both a hidden action=blah fallback (so Enter-key submission triggers the default save) and real submit buttons named action with their own values. When a button is clicked, the browser submits BOTH values and the servlet layer exposes only the first one - the hidden blah - to setAction(String), which would silently run the default save instead of the requested operation. This helper scans the raw parameter array for any real action value before falling back.

      Parameters:
      action - the single action value seen by setAction(), may be null
      settings - raw parameter map as passed to setSettings(), may be null
      Returns:
      the clicked operation if present, else the fallback, else null
    • containsXSS

      private boolean containsXSS(String val)
      Check for common XSS patterns.
      Parameters:
      val - the value to test; null or empty is not XSS
      Returns:
      true if the value contains a script tag, inline event handler or another common XSS pattern
    • storeMethod

      public void storeMethod(String val)
      Call this to prevent changes using GET.
      Parameters:
      val - the request method
    • storeWriter

      public void storeWriter(Writer out)
      Store the output writer for inline form processing.
      Parameters:
      out - the writer inline form processing writes its output to
    • processForm

      protected abstract void processForm()
      Implement this to perform the final processing (in turn, adding formNotice and formError messages, etc)

      Will only be called if _action is non-null and the nonce is valid.

    • addFormError

      protected void addFormError(String errorMsg)
      Add an error message to display Use if it does not include a link. Escapes '<' and '>' before queueing.
      Parameters:
      errorMsg - the error message
    • addFormError

      protected void addFormError(String errorMsg, boolean canClose)
      Add an error message to display Use if it does not include a link. Escapes '<' and '>' before queueing.
      Parameters:
      errorMsg - the error message
      canClose - If true, the message can be closed by the user.
    • addFormNotice

      protected void addFormNotice(String msg)
      Add a non-error message to display Use if it does not include a link. Escapes '<' and '>' before queueing.
      Parameters:
      msg - the notice message
    • addFormNotice

      protected void addFormNotice(String msg, boolean canClose)
      Add a non-error message to display Use if it does not include a link. Escapes '<' and '>' before queueing.
      Parameters:
      msg - the notice message
      canClose - If true, the message can be closed by the user.
    • addFormNoticeNoEscape

      protected void addFormNoticeNoEscape(String msg)
      Add a non-error message to display Use if it includes a link or other formatting. Does not escape '<' and '>' before queueing.
      Parameters:
      msg - the notice message
    • addFormNoticeNoEscape

      protected void addFormNoticeNoEscape(String msg, boolean canClose)
      Add a non-error message to display Use if it includes a link or other formatting. Does not escape '<' and '>' before queueing.
      Parameters:
      msg - the notice message
      canClose - If true, the message can be closed by the user.
    • addFormErrorNoEscape

      protected void addFormErrorNoEscape(String msg)
      Add an error message to display Use if it includes a link or other formatting. Does not escape '<' and '>' before queueing.
      Parameters:
      msg - the error message
    • addFormErrorNoEscape

      protected void addFormErrorNoEscape(String msg, boolean canClose)
      Add an error message to display Use if it includes a link or other formatting. Does not escape '<' and '>' before queueing.
      Parameters:
      msg - the error message
      canClose - If true, the message can be closed by the user.
    • getAllMessages

      public String getAllMessages()
      Display everything, wrap it in a div for consistent presentation.
      Returns:
      the queued errors and notices wrapped in a div, or an empty string if there are none
    • getErrors

      public String getErrors()
      Display any error messages (processing the form if it hasn't been yet).
      Returns:
      an unordered list of the queued error messages, or an empty string if there are none
    • getNotices

      public String getNotices()
      Display any non-error messages (processing the form if it hasn't been yet).
      Returns:
      an unordered list of the queued notice messages, or an empty string if there are none
    • validate

      private void validate()
      Make sure the nonce was set correctly, otherwise someone could just create a link like /confignet.jsp?hostname=localhost and break the user's node (or worse).
    • process

      private void process()
      Processes the submitted form.
    • render

      private static String render(List<FormHandler.Message> source)
      Renders the messages as html.
      Parameters:
      source - the messages to render
      Returns:
      the html text
    • _t

      public String _t(String s)
      Translate a string.
      Parameters:
      s - the string to translate
      Returns:
      the translated string
    • _t

      public String _t(String s, Object o)
      Translate a string with a parameter This is a lot more expensive than _t(s), so use sparingly.
      Parameters:
      s - string to be translated containing {0} The {0} will be replaced by the parameter. Single quotes must be doubled, i.e. ' -> '' in the string.
      o - parameter, not translated. To translate parameter also, use _t("foo {0} bar", _t("baz")) Do not double the single quotes in the parameter. Use autoboxing to call with ints, longs, floats, etc.
      Returns:
      the translated string
    • _t

      public String _t(String s, Object o, Object o2)
      Translate a string with two parameters.
      Parameters:
      s - the string to translate containing {0} and {1}
      o - the first parameter
      o2 - the second parameter
      Returns:
      the translated string
    • _x

      public static String _x(String s)
      Mark a string for extraction by xgettext and translation. Use this only in static initializers. It does not translate!
      Parameters:
      s - the string to mark
      Returns:
      the string unchanged; marking it is what lets xgettext find it