Class BasicRestDebugFormatter
- All Implemented Interfaces:
RestDebugFormatter
- Direct Known Subclasses:
BasicTestRestDebugFormatter
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,
formatBodyemits only the suppression placeholder + byte count — always, even if aRestDebugBodyScrubberis configured (the scrubber is never invoked). - Renderable content only. Even when opted in, only renderable content (see
RestDebugFormatter.isBodyRenderable(String), plus an identityContent-Encoding) is dumped; binary/unknown/compressed content yields a distinct non-renderable placeholder. - Fail-closed scrubber. When the gate is set and a
RestDebugBodyScrubberis configured, its output is dumped (then sanitized and capped); if it throws or returnsnull , the body fails closed to a placeholder — never the raw body.
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 Summary
FieldsModifier and TypeFieldDescriptionprotected intThe body capture cap in bytes.protected RestDebugBodyScrubberOptional body scrubber applied to body text when the master gate is set.static final intDefault body capture cap, in bytes (8 KB).protected intPer header name/value length cap after masking/escaping.protected intCap on emitted header values per block.protected intCap on values scanned while computing omitted counts.protected intRendered URI length cap.The set of header names whose values are masked.Fields inherited from interface org.apache.juneau.rest.server.logging.RestDebugFormatter
DEFAULT_MAX_URI_LENGTH -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionaddRedactedHeaders(Collection<String> value) Extends the redacted-header set additively (keeps the built-in widened protections).intbodyCap()Returns the maximum number of request/response body bytes to capture for theFINEST-tier body rendering.bodyCap(int value) Overrides the body capture cap.Sets the body scrubber applied to body text when theJUNEAU_REST_DEBUG_ALLOW_DUMP_BODIESgate is set.formatBasic(RestRequest req, RestResponse res) Renders the basic (INFO-tier) portion of the debug record.formatBody(RestRequest req, RestResponse res) Renders the body (FINEST-tier) portion of the debug record.formatHeaders(RestRequest req, RestResponse res) Renders the headers (FINE-tier) portion of the debug record.maxFieldLength(int value) Overrides the per header name/value length cap.maxHeaders(int value) Overrides the cap on emitted header values per block.maxHeaderScan(int value) Overrides the cap on values scanned while computing omitted counts.maxUriLength(int value) Overrides the rendered URI length cap.redactedHeaders(Collection<String> value) Overrides the redacted-header set (replaces the built-in widened set).statusLine(jakarta.servlet.http.HttpServletRequest req, jakarta.servlet.http.HttpServletResponse res) Renders the basic status line ([status] HTTP method uri) directly from servlet objects.Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface org.apache.juneau.rest.server.logging.RestDebugFormatter
isBodyRenderable
-
Field Details
-
DEFAULT_BODY_CAP
Default body capture cap, in bytes (8 KB).- See Also:
-
redactedHeaders
The set of header names whose values are masked. Overridable viaredactedHeaders(Collection). -
bodyScrubber
Optional body scrubber applied to body text when the master gate is set. -
bodyCap
The body capture cap in bytes. Overridable viabodyCap(int). -
maxHeaders
Cap on emitted header values per block. Overridable viamaxHeaders(int). -
maxHeaderScan
Cap on values scanned while computing omitted counts. Overridable viamaxHeaderScan(int). -
maxFieldLength
Per header name/value length cap after masking/escaping. Overridable viamaxFieldLength(int). -
maxUriLength
Rendered URI length cap. Overridable viamaxUriLength(int).
-
-
Constructor Details
-
BasicRestDebugFormatter
public BasicRestDebugFormatter()Constructor. -
BasicRestDebugFormatter
Constructor.Provided so subclasses can be instantiated through the
BeanInstantiatorchain (constructor injection).- Parameters:
beanStore- The bean store. Ignored by the default implementation.
-
-
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 benull .- 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 benull .- Returns:
- This object.
-
bodyScrubber
Sets the body scrubber applied to body text when theJUNEAU_REST_DEBUG_ALLOW_DUMP_BODIESgate 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, ornull for none (the default, which dumps raw when gated).- Returns:
- This object.
-
bodyCap
Overrides the body capture cap.- Parameters:
value- The new cap in bytes.- Returns:
- This object.
-
maxHeaders
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
Description copied from interface:RestDebugFormatterReturns the maximum number of request/response body bytes to capture for theFINEST-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:
bodyCapin interfaceRestDebugFormatter- Returns:
- The body capture cap in bytes.
-
formatBasic
Description copied from interface:RestDebugFormatterRenders the basic (INFO-tier) portion of the debug record.Always invoked. Typically a single status line such as
[200] HTTP GET /foo.- Specified by:
formatBasicin interfaceRestDebugFormatter- Parameters:
req- The current REST request. Nevernull .res- The current REST response. Nevernull .- 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:RestDebugFormatterRenders 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 noRestRequest/RestResponseto render through. The method and URI are alwayssanitized(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 appliesRestDebugFormatter.DEFAULT_MAX_URI_LENGTH;BasicRestDebugFormatteroverrides it to apply its configurablemaxUriLength.The query string is intentionally excluded (matching
HttpServletRequest.getRequestURI()), so plaintext?token=…disclosure is never re-introduced through this path.- Specified by:
statusLinein interfaceRestDebugFormatter- Parameters:
req- The servlet request. Nevernull .res- The servlet response. Nevernull .- Returns:
- The rendered, sanitized status line.
-
formatHeaders
Description copied from interface:RestDebugFormatterRenders the headers (FINE-tier) portion of the debug record.Appended to
RestDebugFormatter.formatBasic(RestRequest,RestResponse)when the resolved logger is atFINE-or-finer. The default returns the empty string.- Specified by:
formatHeadersin interfaceRestDebugFormatter- Parameters:
req- The current REST request. Nevernull .res- The current REST response. Nevernull .- Returns:
- The rendered headers portion. Never
null .
-
formatBody
Description copied from interface:RestDebugFormatterRenders 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:
formatBodyin interfaceRestDebugFormatter- Parameters:
req- The current REST request. Nevernull .res- The current REST response. Nevernull .- Returns:
- The rendered body portion. Never
null .
-