Module: Oddb2xml::ProxyCheck
- Defined in:
- lib/oddb2xml/proxy_check.rb
Overview
Preflight connectivity check. Run once at the very start of a CLI run, it probes every outbound host oddb2xml needs (honouring the http(s)_proxy environment) and prints a loud warning if any host is blocked by the proxy (HTTP 407 on an allow-list proxy such as Aspectra’s Skyhigh gateway) or is otherwise unreachable. It never aborts the run – downloads still proceed and fail individually as before; this just surfaces the cause up front instead of leaving the user to decode a later Errno/empty-output symptom. See issue #121.
Constant Summary collapse
- BASE_HOSTS =
host => human-readable description of what breaks when it is unreachable. Hosts only needed for certain options are added conditionally (see #hosts_for).
{ "files.refdata.ch" => "Refdata articles", "www.swissmedic.ch" => "Swissmedic registrations", "raw.githubusercontent.com" => "ATC codes (cpp2sqlite)" }.freeze
- TIMEOUT =
seconds, per host (open + read); checks run concurrently
6
Class Method Summary collapse
-
.all_hosts ⇒ Object
Full union of every host any run could need, regardless of options.
-
.check_host(host, proxy) ⇒ Object
Returns :ok, :blocked (proxy 407) or :unreachable for a single host.
- .hosts_for(options = {}) ⇒ Object
- .proxy_uri ⇒ Object
-
.report(_options = {}) ⇒ Object
Probe every host and print a full OK/BLOCKED/UNREACHABLE table.
-
.run(options = {}) ⇒ Object
Probe all relevant hosts concurrently and warn about any that fail.
- .warn_about(problems, proxy) ⇒ Object
Class Method Details
.all_hosts ⇒ Object
Full union of every host any run could need, regardless of options. Used by –proxy-check so the report covers everything in one go.
48 49 50 51 52 53 54 55 |
# File 'lib/oddb2xml/proxy_check.rb', line 48 def all_hosts BASE_HOSTS.merge( "epl.bag.admin.ch" => "BAG FHIR data (--fhir)", "id.gs1.ch" => "GS1 NONPHARMA (--firstbase / -b)", "www.spezialitaetenliste.ch" => "BAG Spezialitätenliste", "www.medregbm.admin.ch" => "Medizinalberuferegister (-x address)" ) end |
.check_host(host, proxy) ⇒ Object
Returns :ok, :blocked (proxy 407) or :unreachable for a single host.
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/oddb2xml/proxy_check.rb', line 87 def check_host(host, proxy) http = if proxy Net::HTTP.new(host, 443, proxy.host, proxy.port, proxy.user, proxy.password) else Net::HTTP.new(host, 443) end http.use_ssl = true http.verify_mode = OpenSSL::SSL::VERIFY_NONE http.open_timeout = TIMEOUT http.read_timeout = TIMEOUT http.start do |h| res = h.head("/") return :blocked if res.code.to_s == "407" return :ok # any HTTP answer (200/301/403/404/...) means the host is reachable end rescue => error msg = error..to_s.downcase return :blocked if msg.include?("407") || msg.include?("authenticationrequired") || msg.include?("proxy") :unreachable end |
.hosts_for(options = {}) ⇒ Object
37 38 39 40 41 42 43 44 |
# File 'lib/oddb2xml/proxy_check.rb', line 37 def hosts_for( = {}) hosts = BASE_HOSTS.dup hosts["epl.bag.admin.ch"] = "BAG FHIR data (--fhir)" if [:fhir] hosts["id.gs1.ch"] = "GS1 NONPHARMA (--firstbase / -b)" if [:firstbase] hosts["www.spezialitaetenliste.ch"] = "BAG Spezialitätenliste" unless [:fhir] hosts["www.medregbm.admin.ch"] = "Medizinalberuferegister (-x address)" if [:address] hosts end |
.proxy_uri ⇒ Object
28 29 30 31 32 33 34 35 |
# File 'lib/oddb2xml/proxy_check.rb', line 28 def proxy_uri env = ENV["https_proxy"] || ENV["HTTPS_PROXY"] || ENV["http_proxy"] || ENV["HTTP_PROXY"] return nil if env.nil? || env.empty? env = "http://#{env}" unless env.start_with?("http") URI.parse(env) rescue URI::InvalidURIError nil end |
.report(_options = {}) ⇒ Object
Probe every host and print a full OK/BLOCKED/UNREACHABLE table. Returns true when all hosts are reachable. Used by ‘oddb2xml –proxy-check`.
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/oddb2xml/proxy_check.rb', line 59 def report( = {}) proxy = proxy_uri results = all_hosts.map do |host, desc| Thread.new { [host, desc, check_host(host, proxy)] } end.map(&:value).sort_by { |(host, _desc, _status)| host } header = "oddb2xml connectivity check" header += proxy ? " (via proxy #{proxy.host}:#{proxy.port})" : " (no proxy configured)" puts header results.each do |(host, desc, status)| tag = case status when :ok then "OK " when :blocked then "BLOCKED" # proxy returned 407 else "UNREACH" end puts format(" [%s] %-28s %s", tag, host, desc) end unreachable = results.reject { |(_host, _desc, status)| status == :ok } if unreachable.empty? puts "All #{results.size} hosts reachable." true else puts "#{unreachable.size} of #{results.size} host(s) NOT reachable -- downloads using them will fail." false end end |
.run(options = {}) ⇒ Object
Probe all relevant hosts concurrently and warn about any that fail.
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/oddb2xml/proxy_check.rb', line 110 def run( = {}) return if defined?(RSpec) || defined?(VCR) # never touch the network in tests return if ENV["ODDB2XML_SKIP_PROXY_CHECK"] proxy = proxy_uri hosts = hosts_for() results = hosts.map do |host, desc| Thread.new { [host, desc, check_host(host, proxy)] } end.map(&:value) problems = results.reject { |(_host, _desc, status)| status == :ok } return if problems.empty? warn_about(problems, proxy) end |
.warn_about(problems, proxy) ⇒ Object
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/oddb2xml/proxy_check.rb', line 126 def warn_about(problems, proxy) line = "=" * 72 warn line warn " oddb2xml CONNECTIVITY WARNING" warn " The following hosts could not be reached -- the corresponding" warn " downloads will FAIL or produce incomplete data:" problems.each do |(host, desc, status)| tag = (status == :blocked) ? "BLOCKED by proxy (407)" : "UNREACHABLE " warn format(" [%s] %-26s %s", tag, host, desc) end if proxy warn "" warn " Proxy in use: #{proxy.host}:#{proxy.port}" if problems.any? { |(_h, _d, s)| s == :blocked } warn " This looks like an allow-list proxy. Ask your admin to allow the" warn " hosts above (HTTPS/443), or set credentials in http(s)_proxy." end end warn " (Set ODDB2XML_SKIP_PROXY_CHECK=1 to silence this check.)" warn line end |