class VNCTunnel

Attributes

host[RW]
port[RW]

Public Class Methods

new(full_url) click to toggle source
# File lib/foreman_xen/vnc_tunnel.rb, line 8
def initialize(full_url)
  @uri = URI(full_url)
  logger.info(full_url)
  self.host = 'localhost'
  s         = TCPServer.new('127.0.0.1', 0)
  self.port = s.addr[1]
  s.close
  @read_from_server = true
end

Public Instance Methods

logger() click to toggle source
# File lib/foreman_xen/vnc_tunnel.rb, line 37
def logger
  Rails.logger
end
start() click to toggle source
# File lib/foreman_xen/vnc_tunnel.rb, line 18
def start
  client_srv = TCPServer.new('127.0.0.1', port)
  thr        = Thread.new do
    req         = "CONNECT #{@uri.path}?#{@uri.query} HTTP/1.1\r\n\r\n"
    @srv_socket = TCPSocket.open(@uri.host, 80)
    @srv_socket.print req
    header = @srv_socket.readline
    if header == "HTTP/1.1 200 OK\r\n"
      @srv_socket.each_line do |line|
        break if line == "\r\n"
      end
      listen client_srv
    else
      logger.error "Cannot connect to the conosle located at #{uri} reason: #{header}"
      raise "Cannot connect to the console located at #{uri} reason: #{header}"
    end
  end
end

Private Instance Methods

listen(client_srv) click to toggle source
# File lib/foreman_xen/vnc_tunnel.rb, line 43
def listen(client_srv)
  @client_socket = client_srv.accept
  logger.debug 'VNCTunnel Client: client accepted'
  server_listen_thr = Thread.new do
    listen_from_server
  end
  begin
    loop do
      begin
        data = @client_socket.read_nonblock(1024)
        break if data.nil?
        @srv_socket.write(data)
      rescue IO::WaitReadable => e
        IO.select([@client_socket])
        retry
      end
    end
  rescue EOFError
  rescue Exception => e
    logger.error "VNCTunnel Client: unexpected exception #{e}"
  ensure
    @read_from_server = false
    @client_socket.close
    @srv_socket.close
  end
  logger.debug 'VNCTunnel Client is stopping'
end
listen_from_server() click to toggle source
# File lib/foreman_xen/vnc_tunnel.rb, line 71
def listen_from_server
  logger.debug 'VNCTunnel Server is listening'
  begin
    while @read_from_server
      begin
        data = @srv_socket.read_nonblock(1024)
        @client_socket.write(data)
      rescue IO::WaitReadable => e
        retry unless IO.select([@srv_socket], nil, nil, 60).nil?
      end
    end
  rescue EOFError
  rescue Exception => e
    logger.error "VNCTunnel Server: unexpected exception #{e}"
  end
  logger.debug('VNCTunnel Server is stopping')
end