class Gems::RedactedOutput
Wraps the IO that receives HTTP debug output, redacting the credentials it would otherwise write in the clear
Net::HTTP writes every request it sends and every response it reads to the debug output, headers and body alike, which carry the API key, the basic authentication credentials, the one-time passcode, the OIDC ID token of a token exchange, the API key an API key or token exchange response returns, the one-time passcode a WebAuthn verification returns, and the credentials of a proxy. Those values are replaced before they reach the IO, so that debug output can be kept where the credentials should not be.
Net::HTTP writes a response body as it reads it, a line for each read from the socket, so a credential the body carries can be split across two of those lines, where neither half matches the pattern that redacts it. A body sent in chunks is read a chunk at a time, each between the line that says how many bytes it is reading and the line that says how many it read, with the size of the next chunk and the line break that ends each one read in between, so a credential can be split across two chunks as well. The lines of a body are therefore held until the response is done, which Net::HTTP writes a line of its own for, and the parts of the body are joined into one line, written where its first part was read, before they are redacted; the lines around them are written as they were. A connection with a debug output asks for its responses uncompressed (see {Connection}), since a compressed body is written as the bytes it was sent as, which no pattern can find a credential in.
@api private
Constants
- REDACTION
-
The value written in place of a credential
Attributes
The IO the redacted output is written to @api private @return [IO] the IO @example Get the IO
output.output
Public Class Methods
Initialize a new RedactedOutput
@api private @param output [IO] the IO to write the redacted output to @return [RedactedOutput] a new instance @example Wrap an IO
output = Gems::RedactedOutput.new($stderr)
# File lib/gems/redacted_output.rb, line 76 def initialize(output) @output = output end
Public Instance Methods
Write debug output, with credentials redacted
The lines of a response body are held until the response is done, and written, with the parts of the body joined, before whatever is written next.
@api private @param string [String] the debug output @return [RedactedOutput] self, so that writes can be chained as they can to an IO @example Write debug output
output << '<- "GET / HTTP/1.1\r\nAuthorization: key\r\n\r\n"'
# File lib/gems/redacted_output.rb, line 90 def <<(string) if string.start_with?(READING) lines = @lines ||= [] #: Array[String] lines << string @reading = true elsif (lines = @lines) hold(lines, string) else write(string) end self end