Class: GitHubPages::HealthCheck
- Inherits:
-
Object
- Object
- GitHubPages::HealthCheck
- Defined in:
- lib/github-pages-health-check.rb,
lib/github-pages-health-check/error.rb,
lib/github-pages-health-check/version.rb,
lib/github-pages-health-check/cloudflare.rb,
lib/github-pages-health-check/errors/deprecated_ip.rb,
lib/github-pages-health-check/errors/invalid_cname.rb,
lib/github-pages-health-check/errors/invalid_a_record.rb,
lib/github-pages-health-check/errors/not_served_by_pages.rb
Defined Under Namespace
Classes: CloudFlare, DeprecatedIP, Error, InvalidARecord, InvalidCNAME, NotServedByPages
Constant Summary collapse
- LEGACY_IP_ADDRESSES =
%w[ 207.97.227.245 204.232.175.78 199.27.73.133 ]- CURRENT_IP_ADDRESSES =
%w[ 192.30.252.153 192.30.252.154 ]- TIMEOUT =
DNS and HTTP timeout, in seconds
10- TYPHOEUS_OPTIONS =
{ :followlocation => true, :timeout => TIMEOUT, :accept_encoding => "gzip", :method => :head, :headers => { "User-Agent" => "Mozilla/5.0 (compatible; GitHub Pages Health Check/#{VERSION}; +https://github.com/github/pages-health-check)" } }
- VERSION =
"0.5.0"
Instance Attribute Summary collapse
-
#domain ⇒ Object
Returns the value of attribute domain.
Instance Method Summary collapse
-
#a_record? ⇒ Boolean
Is this domain’s first response an A record?.
-
#apex_domain? ⇒ Boolean
Is this domain an SLD, meaning a CNAME would be innapropriate.
-
#check! ⇒ Object
(also: #valid!)
Runs all checks, raises an error if invalid.
- #cloudflare_ip? ⇒ Boolean
-
#cname_record? ⇒ Boolean
Is this domain’s first response a CNAME record?.
-
#dns ⇒ Object
(also: #dns_resolves?)
Returns an array of DNS answers.
-
#dns? ⇒ Boolean
Are we even able to get the DNS record?.
-
#github_domain? ⇒ Boolean
Is this domain owned by GitHub?.
-
#initialize(domain) ⇒ HealthCheck
constructor
A new instance of HealthCheck.
- #inspect ⇒ Object
-
#old_ip_address? ⇒ Boolean
Does this domain have any A record that points to the legacy IPs?.
-
#pages_domain?(domain = domain()) ⇒ Boolean
Is the given cname a pages domain?.
-
#pointed_to_github_pages_ip? ⇒ Boolean
Is the domain’s first response an A record to a valid GitHub Pages IP?.
-
#pointed_to_github_user_domain? ⇒ Boolean
Is the domain’s first response a CNAME to a pages domain?.
-
#proxied? ⇒ Boolean
Does this non-GitHub-pages domain proxy a GitHub Pages site?.
-
#reason ⇒ Object
Return the error, if any.
- #served_by_pages? ⇒ Boolean
-
#should_be_a_record? ⇒ Boolean
Should the domain be an apex record?.
- #to_hash ⇒ Object (also: #to_h)
- #to_json ⇒ Object
- #to_s ⇒ Object
-
#valid? ⇒ Boolean
Runs all checks, returns true if valid, otherwise false.
-
#valid_domain? ⇒ Boolean
Is this a valid domain that PublicSuffix recognizes? Used as an escape hatch to prevent false positves on DNS checkes.
Constructor Details
#initialize(domain) ⇒ HealthCheck
Returns a new instance of HealthCheck.
48 49 50 |
# File 'lib/github-pages-health-check.rb', line 48 def initialize(domain) @domain = domain end |
Instance Attribute Details
#domain ⇒ Object
Returns the value of attribute domain.
22 23 24 |
# File 'lib/github-pages-health-check.rb', line 22 def domain @domain end |
Instance Method Details
#a_record? ⇒ Boolean
Is this domain’s first response an A record?
96 97 98 |
# File 'lib/github-pages-health-check.rb', line 96 def a_record? dns.first.class == Net::DNS::RR::A if dns? end |
#apex_domain? ⇒ Boolean
Is this domain an SLD, meaning a CNAME would be innapropriate
112 113 114 115 116 |
# File 'lib/github-pages-health-check.rb', line 112 def apex_domain? PublicSuffix.parse(domain).trd == nil rescue false end |
#check! ⇒ Object Also known as: valid!
Runs all checks, raises an error if invalid
185 186 187 188 189 190 191 192 193 |
# File 'lib/github-pages-health-check.rb', line 185 def check! raise InvalidDNS unless dns? return if proxied? raise DeprecatedIP if a_record? && old_ip_address? raise InvalidARecord if valid_domain? && a_record? && !should_be_a_record? raise InvalidCNAME if valid_domain? && !github_domain? && !apex_domain? && !pointed_to_github_user_domain? raise NotServedByPages unless served_by_pages? true end |
#cloudflare_ip? ⇒ Boolean
52 53 54 55 56 |
# File 'lib/github-pages-health-check.rb', line 52 def cloudflare_ip? dns.all? do |answer| answer.class == Net::DNS::RR::A && CloudFlare.controls_ip?(answer.address) end if dns? end |
#cname_record? ⇒ Boolean
Is this domain’s first response a CNAME record?
101 102 103 |
# File 'lib/github-pages-health-check.rb', line 101 def cname_record? dns.first.class == Net::DNS::RR::CNAME if dns? end |
#dns ⇒ Object Also known as: dns_resolves?
Returns an array of DNS answers
72 73 74 75 76 77 78 79 80 |
# File 'lib/github-pages-health-check.rb', line 72 def dns @dns ||= Timeout::timeout(TIMEOUT) do without_warnings do Net::DNS::Resolver.start(absolute_domain).answer if domain end end rescue Exception nil end |
#dns? ⇒ Boolean
Are we even able to get the DNS record?
83 84 85 |
# File 'lib/github-pages-health-check.rb', line 83 def dns? !dns.nil? end |
#github_domain? ⇒ Boolean
Is this domain owned by GitHub?
141 142 143 |
# File 'lib/github-pages-health-check.rb', line 141 def github_domain? !!domain.match(/\.github\.com$/) end |
#inspect ⇒ Object
212 213 214 |
# File 'lib/github-pages-health-check.rb', line 212 def inspect "#<GitHubPages::HealthCheck @domain=\"#{domain}\" valid?=#{valid?}>" end |
#old_ip_address? ⇒ Boolean
Does this domain have any A record that points to the legacy IPs?
89 90 91 92 93 |
# File 'lib/github-pages-health-check.rb', line 89 def old_ip_address? dns.any? do |answer| answer.class == Net::DNS::RR::A && LEGACY_IP_ADDRESSES.include?(answer.address.to_s) end if dns? end |
#pages_domain?(domain = domain()) ⇒ Boolean
Is the given cname a pages domain?
domain - the domain to check, generaly the target of a cname
136 137 138 |
# File 'lib/github-pages-health-check.rb', line 136 def pages_domain?(domain = domain()) !!domain.match(/^[\w-]+\.github\.(io|com)\.?$/i) end |
#pointed_to_github_pages_ip? ⇒ Boolean
Is the domain’s first response an A record to a valid GitHub Pages IP?
129 130 131 |
# File 'lib/github-pages-health-check.rb', line 129 def pointed_to_github_pages_ip? dns.first.class == Net::DNS::RR::A && CURRENT_IP_ADDRESSES.include?(dns.first.value) if dns? end |
#pointed_to_github_user_domain? ⇒ Boolean
Is the domain’s first response a CNAME to a pages domain?
124 125 126 |
# File 'lib/github-pages-health-check.rb', line 124 def pointed_to_github_user_domain? dns.first.class == Net::DNS::RR::CNAME && pages_domain?(dns.first.cname.to_s) if dns? end |
#proxied? ⇒ Boolean
Does this non-GitHub-pages domain proxy a GitHub Pages site?
This can be:
1. A Cloudflare-owned IP address
2. A site that returns GitHub.com server headers, but isn't CNAME'd to a GitHub domain
3. A site that returns GitHub.com server headers, but isn't CNAME'd to a GitHub IP
64 65 66 67 68 69 |
# File 'lib/github-pages-health-check.rb', line 64 def proxied? return unless dns? return true if cloudflare_ip? return false if pointed_to_github_pages_ip? || pointed_to_github_user_domain? served_by_pages? end |
#reason ⇒ Object
Return the error, if any
205 206 207 208 209 210 |
# File 'lib/github-pages-health-check.rb', line 205 def reason check! nil rescue GitHubPages::HealthCheck::Error => e e end |
#served_by_pages? ⇒ Boolean
167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/github-pages-health-check.rb', line 167 def served_by_pages? @served_by_pages ||= begin response = Typhoeus.head(uri, TYPHOEUS_OPTIONS) # Workaround for webmock not playing nicely with Typhoeus redirects # See https://github.com/bblimke/webmock/issues/237 if response.mock? && response.headers["Location"] response = Typhoeus.head(response.headers["Location"], TYPHOEUS_OPTIONS) end (response.mock? || response.return_code == :ok) && response.headers["Server"] == "GitHub.com" end end |
#should_be_a_record? ⇒ Boolean
Should the domain be an apex record?
119 120 121 |
# File 'lib/github-pages-health-check.rb', line 119 def should_be_a_record? !pages_domain? && apex_domain? end |
#to_hash ⇒ Object Also known as: to_h
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/github-pages-health-check.rb', line 145 def to_hash { :uri => uri.to_s, :dns_resolves? => dns?, :proxied? => proxied?, :cloudflare_ip? => cloudflare_ip?, :old_ip_address? => old_ip_address?, :a_record? => a_record?, :cname_record? => cname_record?, :valid_domain? => valid_domain?, :apex_domain? => apex_domain?, :should_be_a_record? => should_be_a_record?, :pointed_to_github_user_domain? => pointed_to_github_user_domain?, :pointed_to_github_pages_ip? => pointed_to_github_pages_ip?, :pages_domain? => pages_domain?, :served_by_pages? => served_by_pages?, :valid? => valid?, :reason => reason } end |
#to_json ⇒ Object
180 181 182 |
# File 'lib/github-pages-health-check.rb', line 180 def to_json to_hash.to_json end |
#to_s ⇒ Object
216 217 218 219 220 |
# File 'lib/github-pages-health-check.rb', line 216 def to_s to_hash.inject(Array.new) do |all, pair| all.push pair.join(": ") end.join("\n") end |
#valid? ⇒ Boolean
Runs all checks, returns true if valid, otherwise false
197 198 199 200 201 202 |
# File 'lib/github-pages-health-check.rb', line 197 def valid? check! true rescue false end |
#valid_domain? ⇒ Boolean
Is this a valid domain that PublicSuffix recognizes? Used as an escape hatch to prevent false positves on DNS checkes
107 108 109 |
# File 'lib/github-pages-health-check.rb', line 107 def valid_domain? PublicSuffix.valid? domain end |