Class: MtaSts::Fetcher

Inherits:
Object
  • Object
show all
Defined in:
lib/mta_sts/fetcher.rb

Overview

HTTPS GET of mta-sts./.well-known/mta-sts.txt (RFC 8461 §3.3)

Defined Under Namespace

Classes: BlockedAddress, Body, CertificateError, Error, HttpError, Timeout

Constant Summary collapse

WELL_KNOWN_PATH =
"/.well-known/mta-sts.txt"
PORT =
443
OPEN_TIMEOUT =
10
READ_TIMEOUT =
10
TOTAL_TIMEOUT =

read_timeout renews per read; this one does not — stops a slow-drip body

30
MAX_BODY_BYTES =
64 * 1024
USER_AGENT =
"mta_sts/#{VERSION} (+https://github.com/mailpiece/mta_sts)"
RESERVED_V4 =

Special-use IPv4 no policy is published in. RFC 1918, loopback and link-local are left to the IPAddr predicates.

%w[
  0.0.0.0/8 100.64.0.0/10 192.0.0.0/24 192.0.2.0/24 192.88.99.0/24
  198.18.0.0/15 198.51.100.0/24 203.0.113.0/24 224.0.0.0/4 240.0.0.0/4
].map { |range| IPAddr.new(range) }.freeze
RESERVED_V6 =
%w[
  ::/128 64:ff9b:1::/48 100::/64 2001::/32 2001:2::/48 2001:db8::/32
  2002::/16 fec0::/10 ff00::/8
].map { |range| IPAddr.new(range) }.freeze
NAT64 =

RFC 6052 §2.2 with a /96 prefix

IPAddr.new("64:ff9b::/96")

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(open_timeout: OPEN_TIMEOUT, read_timeout: READ_TIMEOUT, total_timeout: TOTAL_TIMEOUT, max_body_bytes: MAX_BODY_BYTES, resolver: Resolver.new, permitted: Fetcher.method(:public_address?)) ⇒ Fetcher

Returns a new instance of Fetcher.



101
102
103
104
105
106
107
108
109
110
# File 'lib/mta_sts/fetcher.rb', line 101

def initialize(open_timeout: OPEN_TIMEOUT, read_timeout: READ_TIMEOUT,
               total_timeout: TOTAL_TIMEOUT, max_body_bytes: MAX_BODY_BYTES,
               resolver: Resolver.new, permitted: Fetcher.method(:public_address?))
  @open_timeout = open_timeout
  @read_timeout = read_timeout
  @total_timeout = total_timeout
  @max_body_bytes = max_body_bytes
  @resolver = resolver
  @permitted = permitted
end

Class Method Details

.public_address?(address) ⇒ Boolean

The policy host is named by the domain being delivered to, so where it resolves is a stranger's to choose.

Returns:

  • (Boolean)


59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/mta_sts/fetcher.rb', line 59

def public_address?(address)
  ip = address.is_a?(IPAddr) ? address : IPAddr.new(address.to_s)

  case
  # No resolver legitimately answers with an address wrapped in another,
  # whatever it wraps.
  when ip.ipv4_mapped? || ipv4_compat?(ip) then false
  when ip.ipv4?                           then public_v4?(ip)
  when NAT64.include?(ip)                 then public_v4?(embedded_v4(ip))
  else                                         public_v6?(ip)
  end
rescue IPAddr::Error
  false
end

Instance Method Details

#fetch(host) ⇒ Object



112
113
114
# File 'lib/mta_sts/fetcher.rb', line 112

def fetch(host)
  get(normalize(host))
end