Module: Portless::Health
- Defined in:
- lib/portless/health.rb
Overview
"Is our proxy on this port?" — every proxied response carries the X-Portless-Rb header, so a HEAD probe distinguishes our proxy from any other process holding 443/80/1355. The default proxy is HTTPS, so we try a TLS handshake first (no noisy plaintext-to-TLS errors), then plain HTTP. Mirrors portless's isProxyRunning + discoverState.
Constant Summary collapse
- REQUEST =
"HEAD / HTTP/1.0\r\nHost: rb-portless.localhost\r\n\r\n"
Class Method Summary collapse
-
.discover_port ⇒ Object
The port our proxy is currently on, if any: an explicit marker file, else a probe of the usual suspects.
- .marker?(response) ⇒ Boolean
- .probe_plain(port, timeout) ⇒ Object
- .probe_tls(port, timeout) ⇒ Object
- .proxy_running?(port, timeout: 1.0) ⇒ Boolean
- .read_port_file ⇒ Object
Class Method Details
.discover_port ⇒ Object
The port our proxy is currently on, if any: an explicit marker file, else a probe of the usual suspects.
51 52 53 54 55 56 57 58 59 |
# File 'lib/portless/health.rb', line 51 def discover_port from_file = read_port_file return from_file if from_file && proxy_running?(from_file) candidates = [ Integer(ENV["PORTLESS_PORT"], exception: false), Constants::HTTPS_PORT, Constants::HTTP_PORT, Constants::FALLBACK_PROXY_PORT ].compact candidates.each { |port| return port if proxy_running?(port) } nil end |
.marker?(response) ⇒ Boolean
47 |
# File 'lib/portless/health.rb', line 47 def marker?(response) = response.to_s.downcase.include?(Constants::HEALTH_HEADER) |
.probe_plain(port, timeout) ⇒ Object
37 38 39 40 41 42 43 44 45 |
# File 'lib/portless/health.rb', line 37 def probe_plain(port, timeout) Socket.tcp("127.0.0.1", port, connect_timeout: timeout) do |sock| sock.write(REQUEST) sock.close_write marker?(sock.read(4096)) end rescue StandardError false end |
.probe_tls(port, timeout) ⇒ Object
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/portless/health.rb', line 21 def probe_tls(port, timeout) socket = Socket.tcp("127.0.0.1", port, connect_timeout: timeout) ctx = OpenSSL::SSL::SSLContext.new ctx.verify_mode = OpenSSL::SSL::VERIFY_NONE ssl = OpenSSL::SSL::SSLSocket.new(socket, ctx) ssl.sync_close = true ssl.connect ssl.write(REQUEST) marker?(ssl.read(4096)) rescue StandardError false ensure ssl&.close socket&.close unless ssl end |
.proxy_running?(port, timeout: 1.0) ⇒ Boolean
17 18 19 |
# File 'lib/portless/health.rb', line 17 def proxy_running?(port, timeout: 1.0) probe_tls(port, timeout) || probe_plain(port, timeout) end |
.read_port_file ⇒ Object
61 62 63 64 65 |
# File 'lib/portless/health.rb', line 61 def read_port_file Integer(File.read(State.proxy_port_file).strip, exception: false) rescue StandardError nil end |