Module: Portless::Share::Ngrok
- Defined in:
- lib/portless/share/ngrok.rb
Overview
Expose the local app publicly via ngrok. We point ngrok at the backend port directly (with the app's Host header) rather than tunnelling through our self-signed TLS proxy — simpler and avoids cert-trust issues. Returns { pid:, url: } or nil. EXPERIMENTAL. Mirrors portless's ngrok.ts.
Constant Summary collapse
- API =
"http://127.0.0.1:4040/api/tunnels"
Class Method Summary collapse
- .fetch(url) ⇒ Object
- .poll_public_url(tries: 25) ⇒ Object
- .start(hostname:, backend_port:) ⇒ Object
- .stop(handle) ⇒ Object
Class Method Details
.fetch(url) ⇒ Object
62 63 64 65 66 |
# File 'lib/portless/share/ngrok.rb', line 62 def fetch(url) Net::HTTP.get(URI(url)) rescue StandardError nil end |
.poll_public_url(tries: 25) ⇒ Object
47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/portless/share/ngrok.rb', line 47 def poll_public_url(tries: 25) tries.times do sleep 0.3 body = fetch(API) next unless body tunnels = JSON.parse(body)["tunnels"] || [] url = tunnels.map { |t| t["public_url"] }.compact.find { |u| u.start_with?("https") } return url if url end nil rescue StandardError nil end |
.start(hostname:, backend_port:) ⇒ Object
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/portless/share/ngrok.rb', line 18 def start(hostname:, backend_port:) unless Portless.which("ngrok") warn "rb-portless: ngrok not found — install it (https://ngrok.com/download) to use --ngrok" return nil end pid = Process.spawn("ngrok", "http", backend_port.to_s, "--host-header=#{hostname}", out: File::NULL, err: File::NULL) Process.detach(pid) if (url = poll_public_url) { pid: pid, url: url } else stop(pid: pid) warn "rb-portless: ngrok didn't produce a public URL — is your authtoken set? (`ngrok config add-authtoken <token>`)" nil end rescue StandardError => e warn "rb-portless: ngrok failed (#{e.})" nil end |
.stop(handle) ⇒ Object
40 41 42 43 44 45 |
# File 'lib/portless/share/ngrok.rb', line 40 def stop(handle) pid = handle.is_a?(Hash) ? handle[:pid] : handle Process.kill("TERM", pid) if pid rescue StandardError nil end |