module

Deadfinder

Constants

EXIT_DEAD_FOUND = 2

Exit status for "the scan itself ran fine, but dead links/targets were found". Deliberately distinct from 1, which stays reserved for usage and I/O errors. Only emitted when --fail-on-dead is given: the v1 CLI contract is that a scan always exits 0.

IGNORED_SCHEMES = ["mailto:", "tel:", "sms:", "data:", "file:", "javascript:", "#"]
MAX_INVALID_TARGET_REPORTS = 10

How many individually invalid input lines are reported before switching to a single summary line.

MAX_SITEMAP_DEPTH = 5
STDIN_FILENAME = "-"

deadfinder file - reads the list from STDIN, matching the convention of other CLI tools.

STDOUT_FILENAME = "-"

deadfinder ... -o - streams the report to STDOUT instead of creating a file literally named - in the cwd, so deadfinder url X -f json -o - | jq works. Same spelling as STDIN_FILENAME but the opposite direction, hence a separate name.

UTF8_BOM = "\uFEFF"

Byte-order mark that Windows/Excel-exported URL lists carry on their first line. It is not whitespace, so String#strip leaves it attached to the URL and quietly corrupts the very first target.

VERSION = "2.1.0"

Class methods

calculate_coverage
Source
coverage_data
Source
dead_findings?

True when the run recorded anything dead — a broken link on a page, or a target that was itself broken. Drives the --fail-on-dead exit code.

Source
dead_targets
Source
gen_output(options : Options)
Source
generate_url(text : String, base_url : String) : String | Nil
Source
http_target_error(url : String) : String | Nil

Returns nil when url can be used as a scan target, or a human-readable reason why it cannot. Everything rejected here only produces a confusing failure downstream — a bare domain and a stray shell token both raise "URI is missing a host", file:///etc/hosts parses to an empty host and tries to connect to :80, and ftp://host/x would be fetched as plain HTTP — so callers report the reason and skip the target instead.

Source
ignore_scheme?(url : String) : Bool
Source
mutex
Source
output
Source
read_targets(io : IO, limit : Int32) : Array(String)

Reads scan targets from io, one per line, applying the input rules shared by the pipe and file commands:

  • a leading UTF-8 BOM is dropped, so a list exported from Windows/Excel doesn't lose its first URL
  • surrounding whitespace is trimmed, so a padded line doesn't become a distinct target (and a distinct key) in the report
  • blank lines and # comments are skipped instead of being fetched — neither can be a valid target, and both previously logged an error
  • duplicates are dropped, keeping first-seen order
  • lines that aren't absolute http(s) URLs are reported and skipped rather than handed to the fetcher to fail on
  • reading stops once limit targets are collected, so --limit no longer drains a huge list (or a live stream) first — and, because only real targets are counted, blank/comment lines can't eat into the limit
Source
record_dead_target(target : String, status : Int32, options : Options) : Nil

Records a scan target that is itself dead. Runner#run only ever collects the links found on a page, so before this a URL list whose entries all 404 or refuse connections (the advertised deadfinder file <(subfinder | httpx) workflow) reported nothing at all. The dead/alive rule matches Runner#record_status so --include30x governs targets and links identically.

Source
report_sink
Source
report_sink=(io : IO)
Source
reset_report_sink
Source
reset_state

Clears module-level accumulator state so back-to-back runs in the same process (e.g. tests, embedded usage) start from a clean slate.

Source
run_file(filename : String, options : Options)
Source
run_pipe(options : Options)
Source
run_sitemap(sitemap_url : String, options : Options)
Source
run_url(url : String, options : Options)
Source
run_with_target(target : String, options : Options, app : Runner = Runner.new)
Source
status_cache
Source
valid_target?(target : String) : Bool

True when target can actually be scanned: an absolute URL with an http/https scheme and a non-empty host. Same rules as http_target_error, for callers that only need the yes/no.

Source

Nested types