Addresses review feedback on #3848.
Timeout: the probe now dials a user-defined port, so it can reach a
service that accepts the connection but never completes the TLS
handshake, hanging the request indefinitely. ssl-checker already wires
a "timeout" listener that rejects with "Timed Out", but its defaults
set no timeout, so it never fired. Passing one activates it.
The bundled type declaration is a hand-maintained subset of
https.RequestOptions and omitted "timeout"; it is added there so the
call typechecks against an option the library already supports.
Client gating: "http" is a single monitor type covering both schemes,
so an http:// monitor passed the existing type check and requested a
certificate anyway. With the server now rejecting those, the details
page would surface a 400 on every visit. The scheme is gated client
side to match, and the stat box falls back to "N/A" as before.
Test comment removed as requested; the timeout is covered by a new
assertion in the same file.
Passing the monitor's own port to ssl-checker exposed an adjacent gap found
in review: a plain-HTTP monitor on a non-default port, such as
http://host:8080, now had a TLS handshake attempted against a port that
serves no TLS. That surfaced to the client as a 500 carrying a raw OpenSSL
error ("packet length too long") instead of the previous silent "N/A".
The endpoint never checked the scheme — it was already wrong for http://
monitors, just quietly so, since every such lookup went to port 443. Guard
on the protocol and fail with a 400 before opening a socket.
Adds tests for both plain-HTTP cases (default and custom port), each
asserting the checker is never invoked. Verified by removing the guard:
both fail without it.
fetchMonitorCertificate parsed the monitor URL but passed only the hostname
to ssl-checker, which then defaulted to 443. A monitor on a non-standard
port such as https://host:54321 therefore had the certificate of whatever
answered on 443 inspected instead of its own, surfacing as "N/A" in the
certificate expiry box when nothing was listening there.
URL.port is an empty string for default ports, so it is mapped to 443
explicitly rather than passed through Number(), which would have yielded
NaN. ssl-checker already accepts the port via SSLOptions, so no dependency
or signature change is needed.
Adds a regression suite covering the reported case (non-standard port), the
default-port fallback, an explicit :443, and the NaN guard. Verified by
reverting the fix: the three port assertions fail without it.
Fixes#3646
- Bare IP addresses and non-domain hosts (localhost, IPv6) now return a
null expiry instead of throwing, so they no longer spam error logs.
- Extract the registrable domain with tldts instead of walking up
hostname labels, so a subdomain can never accidentally return its
parent domain's expiry date.
- Cache WHOIS lookups per registrable domain (1h positive, 10min
negative) so visiting details pages does not re-query the registry
every time.
Addresses review feedback on #3834.
Adds a GET /monitors/domain/:monitorId endpoint that looks up the
registrable domain's WHOIS expiry date (walking up from subdomains),
and displays it next to the certificate expiry on the uptime details
page.
Fixes#2094