Class: Caldecott::Client::CaldecottClient

Inherits:
Object
  • Object
show all
Defined in:
lib/caldecott-client/client.rb

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ CaldecottClient

Returns a new instance of CaldecottClient.

Raises:



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/caldecott-client/client.rb', line 55

def initialize(options)
  raise InvalidTunnelUrl, "Tunnel URL is required" unless options[:tun_url]

  if options[:log_file]
    Caldecott.logger = Logger.new(options[:log_file])
  end

  Caldecott.logger.level = logger_severity_from_string(options[:log_level])

  @logger = Caldecott.logger

  @local_port = options[:local_port] || 20000

  @tunnel_url = sanitize_url(options[:tun_url])

  @tunnel_options = {
      :dst_host => options[:dst_host],
      :dst_port => options[:dst_port],
      :token => options[:auth_token]
  }

  @closed = false
end

Instance Method Details

#closeObject



79
80
81
# File 'lib/caldecott-client/client.rb', line 79

def close
  @closed = true
end

#closed?Boolean

Returns:

  • (Boolean)


83
84
85
# File 'lib/caldecott-client/client.rb', line 83

def closed?
  @closed
end

#control_threads(tunnel, conn, threads) ⇒ Object



131
132
133
134
135
136
137
138
139
140
# File 'lib/caldecott-client/client.rb', line 131

def control_threads(tunnel, conn, threads)
  loop do
    if tunnel.closed? || conn.closed? || closed?
      threads.each { |t| t.exit }
      break
    end

    sleep(0.01)
  end
end

#create_tunnelObject



127
128
129
# File 'lib/caldecott-client/client.rb', line 127

def create_tunnel
  Tunnel.for_url(@tunnel_url, @tunnel_options)
end

#read_from_tunnel(tunnel, conn) ⇒ Object



142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/caldecott-client/client.rb', line 142

def read_from_tunnel(tunnel, conn)
  in_buf = ""
  loop do
    in_buf << tunnel.read unless tunnel.closed?

    break if in_buf.size < 1

    if in_buf.size > 0
      n_sent = conn.send(in_buf.slice!(0, BUFFER_SIZE), 0)
      @logger.debug("l <- t: #{n_sent}, buf: #{in_buf.size}")
    end
  end
end

#startObject



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/caldecott-client/client.rb', line 87

def start
  @logger.info("Starting the tunnel on port #{@local_port}...")
  server = TCPServer.new("127.0.0.1", @local_port)
  @logger.info("Tunnel started")

  loop do
    # server.accept is blocking until request is received
    Thread.new(server.accept) do |conn|
      @logger.info("Connection accepted on #{@local_port}...")

      tunnel = create_tunnel
      tunnel.start

      w = Thread.new do
        write_to_tunnel(tunnel, conn)
      end

      r = Thread.new do
        read_from_tunnel(tunnel, conn)
      end

      c = Thread.new do
        control_threads(tunnel, conn, [w, r])
      end

      r.join
      w.join
      c.join

      @logger.info("Closing tunnel")
      conn.close
      tunnel.stop

      break if closed?
    end
  end

  server.close
end

#write_to_tunnel(tunnel, conn) ⇒ Object



156
157
158
159
160
161
162
163
164
165
# File 'lib/caldecott-client/client.rb', line 156

def write_to_tunnel(tunnel, conn)
  loop do
    out_data = conn.recv(BUFFER_SIZE)

    break if out_data.size < 1 # connection closed

    @logger.debug("l -> t: #{out_data.size}")
    tunnel.write(out_data)
  end
end