Class: Rack::Tunnel
- Inherits:
-
Object
- Object
- Rack::Tunnel
- Defined in:
- lib/rack/tunnel.rb
Defined Under Namespace
Classes: Error
Constant Summary collapse
- VERSION =
'0.1.1'- HEADER =
'X-Tunnel-Uri'
Instance Method Summary collapse
- #call(env) ⇒ Object
- #command(local_port) ⇒ Object
- #establish_tunnel(local_port) ⇒ Object
-
#initialize(app, uri) ⇒ Tunnel
constructor
A new instance of Tunnel.
- #wait_for_tunnel ⇒ Object
Constructor Details
#initialize(app, uri) ⇒ Tunnel
Returns a new instance of Tunnel.
10 11 12 13 14 15 16 |
# File 'lib/rack/tunnel.rb', line 10 def initialize(app, uri) @app, @uri = app, URI.parse(uri) if @uri.port <= 1024 && @uri.user != 'root' raise Error, "root user required for port #{@uri.port}" end end |
Instance Method Details
#call(env) ⇒ Object
18 19 20 21 |
# File 'lib/rack/tunnel.rb', line 18 def call(env) establish_tunnel(env['SERVER_PORT']) unless @tunnel_established @app.call(env.merge(HEADER => @uri.to_s)) end |
#command(local_port) ⇒ Object
35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/rack/tunnel.rb', line 35 def command(local_port) cmd = %w"ssh" cmd << "-R" << "0.0.0.0:#{@uri.port}:localhost:#{local_port}" cmd << @uri.host cmd << "-l" << @uri.user cmd << "-o" << "TCPKeepAlive=yes" cmd << "-o" << "ServerAliveInterval=30" cmd << "-o" << "ServerAliveCountMax=10" cmd << "-o" << "GatewayPorts=yes" cmd << "-N" cmd end |
#establish_tunnel(local_port) ⇒ Object
23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/rack/tunnel.rb', line 23 def establish_tunnel(local_port) pid, _ = Open4.popen4(*command(local_port)) at_exit do Process.kill(9, pid) Process.wait end wait_for_tunnel @tunnel_established = true end |
#wait_for_tunnel ⇒ Object
49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/rack/tunnel.rb', line 49 def wait_for_tunnel Timeout::timeout(30) do begin return TCPSocket.new(@uri.host, @uri.port) rescue Errno::ECONNREFUSED retry rescue => e raise Error, e. end end end |