Class BasicRestDebugFormatter

java.lang.Object
org.apache.juneau.rest.server.logging.BasicRestDebugFormatter
All Implemented Interfaces:
RestDebugFormatter
Direct Known Subclasses:
BasicTestRestDebugFormatter

public class BasicRestDebugFormatter extends Object implements RestDebugFormatter
Default RestDebugFormatter implementation — secure by default.

Renders, cumulatively by tier:

  • Basic (INFO) — a single status line ([status] HTTP method uri), with the method and URI sanitized and the URI length-capped.
  • Headers (FINE) — request/response header blocks (every value of every header, credential-bearing values masked, all names/values sanitized and bounded), plus request/response lengths and the request execution time.
  • Body (FINEST) — request/response bodies, but only if the operator has opted in (see below); otherwise a suppression placeholder + byte count.
Secure-by-default body handling

Bodies are never dumped by default. Dumping is a deliberate operator opt-in behind a single environment-variable master gate, JUNEAU_REST_DEBUG_ALLOW_DUMP_BODIES:

  • Env-only. It is an environment variable, never a system property, and has no system-property fallback — application code cannot flip it at runtime.
  • Truthy semantics. The raw value is trimmed, then a non-empty value enables dumping except case-insensitive false/0; unset/empty/all-whitespace disables. It is resolved once and cached, making it an emergency kill switch.
  • Gate subordinate. With the gate unset, formatBody emits only the suppression placeholder + byte count — always, even if a RestDebugBodyScrubber is configured (the scrubber is never invoked).
  • Renderable content only. Even when opted in, only renderable content (see RestDebugFormatter.isBodyRenderable(String), plus an identity Content-Encoding) is dumped; binary/unknown/compressed content yields a distinct non-renderable placeholder.
  • Fail-closed scrubber. When the gate is set and a RestDebugBodyScrubber is configured, its output is dumped (then sanitized and capped); if it throws or returns null, the body fails closed to a placeholder — never the raw body.
No bytes appear in any placeholder in any representation.
Header redaction and sanitization

Values for a widened, formatter-local credential-bearing header set are masked with RedactedHeaders.REDACTED. The set starts from RedactedHeaders.DEFAULT plus X-Auth-Token, X-Authorization, WWW-Authenticate, Referer, and Location; the shared RedactedHeaders.DEFAULT is left unchanged. Matching is case-insensitive with separator folding (-/_ stripped), so X-Auth-Token, X_Auth_Token, and XAuthToken all match. Replace the set with redactedHeaders(Collection) or extend it with addRedactedHeaders(Collection). Every emitted string (URI/method, header names/values, body text, placeholders) is sanitized against CR/LF/control-char log forging via DebugTextSanitizer, in mask → escape → cap order.

Bounds

Bodies are bounded by bodyCap() bytes (default 8 KB) at capture time; headers by maxHeaders(int)/maxHeaderScan(int)/maxFieldLength(int); the URI by maxUriLength(int). The 8 KB body cap is deliberately smaller than EchoMixin's 1 MB body cap — debug logging is intended for low-volume operator diagnostics; the two caps are independent by design.

See Also:
Since:
10.0.0
  • Field Details

  • Constructor Details

  • Method Details

    • redactedHeaders

      Overrides the redacted-header set (replaces the built-in widened set).
      Parameters:
      value - The new set of header names to mask (case-insensitive, separator-folded). Must not be null.
      Returns:
      This object.
    • addRedactedHeaders

      Extends the redacted-header set additively (keeps the built-in widened protections).
      Parameters:
      value - The header names to add to the masked set (case-insensitive, separator-folded). Must not be null.
      Returns:
      This object.
    • bodyScrubber

      Sets the body scrubber applied to body text when the JUNEAU_REST_DEBUG_ALLOW_DUMP_BODIES gate is set.

      The scrubber only ever runs when the gate is set; it chooses scrubbed-vs-raw once dumping is already permitted. It is fail-closed: a throw or a null return yields a placeholder, never the raw body.

      Parameters:
      value - The scrubber, or null for none (the default, which dumps raw when gated).
      Returns:
      This object.
    • bodyCap

      public BasicRestDebugFormatter bodyCap(int value)
      Overrides the body capture cap.
      Parameters:
      value - The new cap in bytes.
      Returns:
      This object.
    • maxHeaders

      public BasicRestDebugFormatter maxHeaders(int value)
      Overrides the cap on emitted header values per block.
      Parameters:
      value - The new cap. Must be ≥ 0.
      Returns:
      This object.
    • maxHeaderScan

      Overrides the cap on values scanned while computing omitted counts.
      Parameters:
      value - The new cap. Must be ≥ 0.
      Returns:
      This object.
    • maxFieldLength

      Overrides the per header name/value length cap.
      Parameters:
      value - The new cap. Must be ≥ 0.
      Returns:
      This object.
    • maxUriLength

      Overrides the rendered URI length cap.
      Parameters:
      value - The new cap. Must be ≥ 0.
      Returns:
      This object.
    • bodyCap

      public int bodyCap()
      Description copied from interface: RestDebugFormatter
      Returns the maximum number of request/response body bytes to capture for the FINEST-tier body rendering.

      This cap is enforced at capture time by the two-phase pipeline, so memory stays bounded even for large uploads/downloads. Defaults to 8 KB.

      Specified by:
      bodyCap in interface RestDebugFormatter
      Returns:
      The body capture cap in bytes.
    • formatBasic

      Description copied from interface: RestDebugFormatter
      Renders the basic (INFO-tier) portion of the debug record.

      Always invoked. Typically a single status line such as [200] HTTP GET /foo.

      Specified by:
      formatBasic in interface RestDebugFormatter
      Parameters:
      req - The current REST request. Never null.
      res - The current REST response. Never null.
      Returns:
      The rendered basic portion. Never null.
    • statusLine

      public String statusLine(jakarta.servlet.http.HttpServletRequest req, jakarta.servlet.http.HttpServletResponse res)
      Description copied from interface: RestDebugFormatter
      Renders the basic status line ([status] HTTP method uri) directly from servlet objects.

      Used both by RestDebugFormatter.formatBasic(RestRequest,RestResponse) and by the pipeline's no-operation (404/405) path, which has no RestRequest/RestResponse to render through. The method and URI are always sanitized (CR/LF and control characters escaped) so a client-controlled URI cannot forge a log line, and the rendered URI is length-capped. This default applies RestDebugFormatter.DEFAULT_MAX_URI_LENGTH; BasicRestDebugFormatter overrides it to apply its configurable maxUriLength.

      The query string is intentionally excluded (matching HttpServletRequest.getRequestURI()), so plaintext ?token=… disclosure is never re-introduced through this path.

      Specified by:
      statusLine in interface RestDebugFormatter
      Parameters:
      req - The servlet request. Never null.
      res - The servlet response. Never null.
      Returns:
      The rendered, sanitized status line.
    • formatHeaders

      Description copied from interface: RestDebugFormatter
      Renders the headers (FINE-tier) portion of the debug record.

      Appended to RestDebugFormatter.formatBasic(RestRequest,RestResponse) when the resolved logger is at FINE-or-finer. The default returns the empty string.

      Specified by:
      formatHeaders in interface RestDebugFormatter
      Parameters:
      req - The current REST request. Never null.
      res - The current REST response. Never null.
      Returns:
      The rendered headers portion. Never null.
    • formatBody

      Description copied from interface: RestDebugFormatter
      Renders the body (FINEST-tier) portion of the debug record.

      Appended when the resolved logger is at FINEST. Reads the cached request/response bytes. The default returns the empty string.

      Specified by:
      formatBody in interface RestDebugFormatter
      Parameters:
      req - The current REST request. Never null.
      res - The current REST response. Never null.
      Returns:
      The rendered body portion. Never null.